栈的应用——中缀转后缀并计算

该代码实现了一个将中缀表达式转换为后缀表达式,并根据后缀表达式进行计算的程序。主要利用栈数据结构,遵循运算符优先级规则。首先遍历中缀表达式,遇到操作数直接添加到后缀表达式,遇到运算符则根据优先级弹出栈中运算符。最后,通过后缀表达式计算结果,将操作数压栈并进行相应的加减乘除操作。
摘要由CSDN通过智能技术生成

//中缀表达式转后缀表达式
void Mid_To_Ni(char str,int length,Stack res)
str:中缀表达式
length:中缀表达式长度
res:后缀表达式

//根据后缀表达式计算
char compute(Stack s)
s:后缀表达式
return:计算结果

//用栈实现中缀表达式转后缀表达式
#include <stdio.h>
#include <stdlib.h>
//代码中函数返回值:1表示true,0表示false
#define MaxSize 20                  //栈最多可以放几个
typedef struct Stack{
    char str[MaxSize];              //栈顺序表
    int top;                        //栈顶指针
}Stack;

void InitStack(Stack *S){
    S->top=-1;                      //栈顶指针初始化为-1
}
//入栈
int Push(Stack *S,char c){          //进栈函数
    if(S->top>=MaxSize)
        return 0;
    S->top++;
    S->str[S->top]=c;
    //printf("%c",S->str[S->top]);
    //show(*S);
    return 1;
}
//获得栈顶元素
int GetTop(Stack s , char *c){
    if(s.top<0){
        return 0;
    }
    (*c)=s.str[s.top];
    return 1;
}
//出栈
int Pop(Stack *S,char *c){
    if(S->top<0)
        return 0;
    (*c)=S->str[S->top];                //这里要*c,因为传入的是引用变量
    S->top--;
    return 1;
}
//判断栈是否为空
int IsEmptyStack(Stack s){
    if(s.top==-1){
        return 1;
    }
    return 0;
}
//打印一下栈
void show(Stack S){
    //printf("%d",S.top);
    printf("当前栈内元素为:");
    for(int i=0;i<=S.top;i++){          //这里是要<=S.top;因为top是指向栈顶元素,从-1开始的;
        printf("%c\t",S.str[i]);
    }
    printf("\n");
}

//中缀表达式转后缀表达式
void Mid_To_Ni(char *str,int length,Stack* res){
    Stack s;                                    //定义一个栈
    InitStack(&s);                              //初始化
    char chr[length];                           //存储后缀表达式
    int chr_pos = 0;                            //后缀表达式的指针
    for(int i=0;i<length;i++){
        printf("%c",str[i]);
    }
    printf("\n");
    for(int i=0;i<length;i++){                  //遍历输入的算式
        //遇到界限符
        if(str[i]=='('||str[i]==')'){
            if(str[i]=='('){                    //如果是(直接入栈
                Push(&s,str[i]);
            }else{                              //遇到),则依次弹出栈内运算符并加入后缀表达式
                char c;
                Pop(&s,&c);
                while(c!='('){                  //直到弹出(为止
                    chr[chr_pos++]=c;
                    Pop(&s,&c);
                }
            }
        }
        else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'){
        //如果遇到运算符,依次弹出栈内优先级高于或等于当前运算符的所有运算符,并加入后缀表达式
        //若碰到(或栈空则停止,之后再把当前运算符进栈
            if(str[i]=='*'||str[i]=='/'){               //遇到乘除,高于或等于乘除的运算符是*/
                char c;GetTop(s,&c);
                while(GetTop(s,&c)!=0&&c!='('){         //碰到(或栈空则停止
                    if(c=='*'||c=='/'){                 //高于或等于乘除的运算符是*/
                        Pop(&s,&c);

                        chr[chr_pos++]=c;               //加入后缀表达式
                    }else{
                        break;
                    }
                }
                Push(&s,str[i]);                        //再把当前运算符进栈
            }else{
                char c;GetTop(s,&c);
                while(GetTop(s,&c)!=0&&c!='('){
                    Pop(&s,&c);
                    chr[chr_pos++]=c;
                }
                Push(&s,str[i]);
            }
        }else{
            //遇到操作数,直接加入后缀表达式
            chr[chr_pos++]=str[i];
        }
        show(s);
    }

    //将栈中剩余运算符依次弹出,并加入后缀表达式
    char c;
    while(IsEmptyStack(s)!=1){
        Pop(&s,&c);
        chr[chr_pos++]=c;
    }

    //打印后缀表达式,并将后缀表达式压入一个栈
    for(int i=0;i<chr_pos;i++){
        Push(res,chr[i]);
    }
    return chr_pos;     //返回后缀表达式长度
}

//根据后缀表达式计算
char compute(Stack s){
    Stack stack;                                                            //定义一个操作数栈,用于存放操作数
    InitStack(&stack);
    for(int i=0;i<=s.top;i++){                                              //遍历后缀表达式,因为栈的指针是指向栈顶元素所以一定要是<=!!!!!!!!!!
        if(s.str[i]!='+'&&s.str[i]!='-'&&s.str[i]!='*'&&s.str[i]!='/'){     //如果遇到操作数,无脑入栈
            Push(&stack,s.str[i]);
        }else{                                                              //如果是操作符,则弹出操作数栈栈顶的两个元素
            char c;
            Pop(&stack,&c);
            int b = c-'0';        //-'0'是将其转化为整数                    //栈顶元素
            Pop(&stack,&c);
            int a = c-'0';        //-'0'是将其转化为整数                    //次栈顶元素,一定要注意顺序!!!!!
            switch(s.str[i]){
                case '+': Push(&stack,(char)a+b+'0'); break;               //+'0'是将其转化为字符
                case '-': Push(&stack,(char)a-b+'0'); break;
                case '*': Push(&stack,(char)a*b+'0'); break;
                case '/': Push(&stack,(char)a/b+'0'); break;
            }
        }
        show(stack);                                                        //打印操作数栈
    }
    return stack.str[stack.top];                                            //返回计算结果
}

int main()
{
    //char s[11]={'a','+','b','-','(','c','+','d',')','*','m'};
    char s[13]={'7','-','2','*','(','1','+','1',')','-','6','/','3'};
    char chr[13];

    //存储压入栈中的后缀表达式
    Stack stack;
    InitStack(&stack);

    //中缀转后缀
    Mid_To_Ni(s,13,&stack);

    //打印压入栈中的后缀表达式
    for(int i=0;i<=stack.top;i++){
        printf("%c",stack.str[i]);
    }
    printf("\n");
    printf("\n计算结果为:%c",compute(stack));
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值