如何用C语言计算表达式的值,栈的经典应用

声明:这个程序可以计算+,-,*,/,负数,小数

负数用括号括起来例如(-1)

负数的计算过程:(-1)  转变为 (0-1)  哈哈~

分成六个点:

1.我的文件结构

2.顺序堆栈的头文件

3.头文件引入与自定义的常量和类型

4.主处理函数

5.测试的主函数

6.测试结果

1.我的文件结构

有两个文件        1.expCop.c     里面的内容是:头文件与自定义的常量和类型、主处理函数、测试的主函数

                          2.SqeStack.h  里面的内容是:栈的定义与处理函数

2.顺序堆栈的头文件

typedef struct{
    DataType stack[MaxStackSize];
    int top;
}SeqStack;


//栈初始化
void StackInitiate(SeqStack *S){
    S->top = 0;
}
//判断栈是否为空
int StackNotEmpty(SeqStack S){
    if(S.top==0){
        return 0;
    }
    return 1;
}
//入栈
int StackPush(SeqStack *S,DataType x){
    if(S->top>=MaxStackSize){
        printf("堆栈已满无法插入!\n");
        return 0;
    }else{
        S->stack[S->top]=x;
        S->top++;
        return 1;
    }
}
//出栈
int StackPop(SeqStack *S,DataType *d){
    if(S->top<=0){
        printf("StackPop堆栈为空!\n");
        return 0;
    }else{
        S->top--;
        *d = S->stack[S->top];
        return 1;
    }
}
//获取栈顶数据元素
int StackTop(SeqStack S,DataType *d){
    if(S.top<=0){
        printf("StackTop堆栈为空!\n");
        return 0;
    }else{
        *d = S.stack[S.top-1];
        return 1;
    }
}


 3.头文件引入与自定义的常量和类型

typedef char DataType;//定义栈的数据存数的类型
#define MaxStackSize 100//定义栈的大小
#include <stdio.h>//这个不用多说
#include <string.h>//字符串处理(自带)
#include <math.h>//用来处理小数,用到了pow(自带)
#include "SeqStack.h"//这是顺序堆栈的头文件(需要自己建立)

4.主处理函数

double expressionComputation(char *exp){
    SeqStack myStack;//对操作符进行中缀到后缀
    StackInitiate(&myStack);
    double num[100];//保存操作数 注:在弹出操作符的以后要立刻取出num最后面两个数字进行运算后存回num中
    int numSize = 0;
    int i,j;
    int spot = 0;
    char c;
    for(i=0;i<strlen(exp);i++){
        if((exp[i]=='0'||exp[i]=='1'||exp[i]=='2'||exp[i]=='3'||exp[i]=='4'||exp[i]=='5'||exp[i]=='6'||exp[i]=='7'||exp[i]=='8'||exp[i]=='9')&&spot==0){
            j=i+1;
            while(exp[j]=='0'||exp[j]=='1'||exp[j]=='2'||exp[j]=='3'||exp[j]=='4'||exp[j]=='5'||exp[j]=='6'||exp[j]=='7'||exp[j]=='8'||exp[j]=='9'){
                j++;
            }
            num[numSize] = num[numSize] + (exp[i]-'0') * pow(10,j-i-1);
            if(j-i-1==0&&exp[j]!='.'){
                numSize++;
            }
            continue;
        }
        if(exp[i]=='.'||spot==1){
            spot=1;
            if(exp[i]=='.'){
                j=0;
                continue;
            }else{
                j--;
            }
            num[numSize] = num[numSize] + (exp[i]-'0') * pow(10,j);
            if(exp[i+1]!='0'&&exp[i+1]!='1'&&exp[i+1]!='2'&&exp[i+1]!='3'&&exp[i+1]!='4'&&exp[i+1]!='5'&&exp[i+1]!='6'&&exp[i+1]!='7'&&exp[i+1]!='8'&&exp[i+1]!='9'){
                numSize++;
                spot=0;
            }
        }
        if(exp[i]=='+'){
            if(!StackNotEmpty(myStack)){
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='-'||c=='+')){
                while(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='-'||c=='+')){
                    StackPop(&myStack,&c);
                    switch(c){
                        case '*':num[numSize-2] = num[numSize-2]*num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '/':num[numSize-2] = num[numSize-2]/num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '-':num[numSize-2] = num[numSize-2]-num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '+':num[numSize-2] = num[numSize-2]+num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                    }
                    if(!StackNotEmpty(myStack)){
                        break;
                    }
                }
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&c=='('){
                StackPush(&myStack,exp[i]);
            }
        }
        if(exp[i]=='-'){
            if(exp[i-1]!='0'&&exp[i-1]!='1'&&exp[i-1]!='2'&&exp[i-1]!='3'&&exp[i-1]!='4'&&exp[i-1]!='5'&&exp[i-1]!='6'&&exp[i-1]!='7'&&exp[i-1]!='8'&&exp[i-1]!='9'&&exp[i-1]!='('&&exp[i-1]!=')'){
                printf("输入格式错误!Tip:负数请加括号如(-1)\n");
                break;
            }
            if(!StackNotEmpty(myStack)){
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='+'||c=='-')){
                while(StackTop(myStack,&c)&&(c=='*'||c=='/'||c=='+'||c=='-')){
                    StackPop(&myStack,&c);
                    switch(c){
                        case '*':num[numSize-2] = num[numSize-2]*num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '/':num[numSize-2] = num[numSize-2]/num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '+':num[numSize-2] = num[numSize-2]+num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                        case '-':num[numSize-2] = num[numSize-2]-num[numSize-1];
                                 numSize--;
                                 num[numSize]=0;
                                 break;
                    }
                    if(!StackNotEmpty(myStack)){
                        break;
                    }
                }
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='('||c==')')){
                StackPush(&myStack,exp[i]);
            }
        }
        if(exp[i]=='*'){
            if(!StackNotEmpty(myStack)||(StackTop(myStack,&c)&&(c=='+'||c=='-'))){
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='/')){
                StackPop(&myStack,&c);
                switch(c){
                    case '/':num[numSize-2] = num[numSize-2]/num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                }
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='('||c==')')){
                StackPush(&myStack,exp[i]);
            }
        }
        if(exp[i]=='/'){
            if(!StackNotEmpty(myStack)||(StackTop(myStack,&c)&&(c=='+'||c=='-'))){
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='*')){
                StackPop(&myStack,&c);
                switch(c){
                    case '*':num[numSize-2] = num[numSize-2]*num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                }
                StackPush(&myStack,exp[i]);
            }else if(StackTop(myStack,&c)&&(c=='('||c==')')){
                StackPush(&myStack,exp[i]);
            }
        }
        if(exp[i]=='('){
            StackPush(&myStack,exp[i]);
            if(exp[i+1]=='-'){
                int k=strlen(exp);
                while(k-1>i){
                    exp[k]=exp[k-1];
                    k--;
                }
                exp[i+1]='0';
            }

        }
        if(exp[i]==')'){
            while(StackTop(myStack,&c)&&c!='('){
                StackPop(&myStack,&c);
                switch(c){
                    case '*':num[numSize-2] = num[numSize-2]*num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                    case '/':num[numSize-2] = num[numSize-2]/num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                    case '+':num[numSize-2] = num[numSize-2]+num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                    case '-':num[numSize-2] = num[numSize-2]-num[numSize-1];
                             numSize--;
                             num[numSize]=0;
                             break;
                }
            }
            StackPop(&myStack,&c);
        }
    }
    while(StackNotEmpty(myStack)){
        StackPop(&myStack,&c);
        switch(c){
            case '*':num[numSize-2] = num[numSize-2]*num[numSize-1];
                     numSize--;
                     num[numSize]=0;
                     break;
            case '/':num[numSize-2] = num[numSize-2]/num[numSize-1];
                     numSize--;
                     num[numSize]=0;
                     break;
            case '+':num[numSize-2] = num[numSize-2]+num[numSize-1];
                     numSize--;
                     num[numSize]=0;
                     break;
            case '-':num[numSize-2] = num[numSize-2]-num[numSize-1];
                     numSize--;
                     num[numSize]=0;
                     break;
        }
    }
    return num[0];//最后的值
}

5.测试的主函数

void main(void){
    char exp[200]="";
    printf("请输入一个表达式\t形如:2+3+(-5)+1.2\n");
    scanf("%s",exp);
    printf("\n结果为:%lf",expressionComputation(exp));
}

6.测试结果

可能会存在其他意想不到的错误,若测试出现其他错误请指正,我会加以修正。

猜你喜欢

转载自blog.csdn.net/z7________/article/details/83120079