中缀表达式转后缀表达式

算法步骤:
初始化一个栈,用于保存暂时还不能确定运算顺序的运算符
从左到右处理各个元素,直到末尾,可能遇到三种情况:

  1. 遇到操作数,直接加入后缀表达式
  2. 遇到界限符,遇到左括号则直接入栈,遇到右括号则依次弹出栈内运算符并加入后缀表达式,直到弹出左括号为止。注意左括号不加入后缀表达式
  3. 遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到了左括号或栈空则停止,之后再把当前运算符入栈

编写程序过程中,扫描到运算符的时候,判断栈中优先级高于当前运算符的情况,注意用GetTop来代替直接Pop, 先判断优先级是否高于当前运算符,为真,则Pop. 并注意continue和break的正确使用

//中缀表达式转后缀表达式
/*  算法步骤:
初始化一个栈,用于保存暂时还不能确定运算顺序的运算符
从左到右处理各个元素,直到末尾,可能遇到三种情况:
4. 遇到操作数,直接加入后缀表达式
5. 遇到界限符,遇到左括号则直接入栈,遇到右括号则依次弹出栈内运算符并加入
后缀表达式,直到弹出左括号为止。注意左括号不加入后缀表达式
3.遇到运算符,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入
后缀表达式,若碰到了左括号或栈空则停止,之后再把当前运算符入栈
*/
//栈的顺序存储结构,用静态数组实现
#include<stdio.h>
#include<string.h>
#define MaxSize 40//定义栈中元素的最大个数
#define ElemType char
typedef struct{
    ElemType data[MaxSize];//存放栈中的元素
    int top;//栈顶指针
}SqStack;//顺序栈

void InitStack(SqStack &s){
    s.top=-1;//初始化栈顶指针
}

bool StackEmpty(SqStack s){
    return s.top==-1;
}

bool Push(SqStack &s,ElemType x){
    if(s.top == MaxSize-1){
        printf("overflow\n");
        return false;
    }
    s.data[++s.top]=x;
    return true;
}

bool Pop(SqStack &s,ElemType &x){
    //先判断栈是否为空
    if(!StackEmpty(s)){
         x = s.data[s.top--];
        return true;
    }

}

bool GetTop(SqStack s,ElemType &x){
    //先判断栈是否为空
    if(!StackEmpty(s)){
        x = s.data[s.top];
        return true;
    }
}

bool DestroyStack(SqStack &s){
    s.top=-1;
}

bool PrintStack(SqStack s){
    int p=s.top;
    if(p==-1){
        printf("\n栈空\n");
        return false;
    }
    printf("Stack is :");
    while(p!=-1){
        printf("%d ",s.data[p--]);
    }
    printf("\n");
}

bool isDigit(char c){
    return (c>='0'&&c<='9');
}

bool isAlpha(char c){
    return ((c>='a'&& c<='z')||(c>='A'&&c<='Z'));
}
//输入字符串,和其长度
bool midToSuffix(char str[],int len){
    SqStack s;
    InitStack(s);
    char ch;
    ElemType topElem='\0';
    for(int i=0;i<len;i++){
        ch=str[i];
        if(isDigit(ch)){
            printf("%c",ch);
            if(!isDigit(str[i+1])){//不是数字的话则输出空格
            printf(" ");
            }
            continue;
        }
        if(isAlpha(ch)){//如果是字母的话
            printf("%c ",ch);
            continue;
        }
        switch(ch){
            //遇到左括号则直接入栈
        case '(':
            Push(s,ch);break;
        case '[':
            Push(s,ch);break;
        case '{':
            Push(s,ch);break;
        //遇到右括号,则依次弹出栈内运算符并加入后缀表达式;
        case ')':
            Pop(s,topElem);
            while(topElem!='('){
                    printf("%c ",topElem);
                    Pop(s,topElem);
                  };
            break;
        case ']':
            Pop(s,topElem);
            while(topElem!='['){
                    Pop(s,topElem);
                    printf("%c ",topElem);
                  };
            break;
        case '}':
            Pop(s,topElem);
            while(topElem!='{'){
                    printf("%c ",topElem);
                    Pop(s,topElem);
                  };
            break;
        case '+':
            GetTop(s,topElem);//获取栈顶元素,这里用GetTop比直接Pop省事甚多
            while(!StackEmpty(s) && topElem != '('&& topElem != '['&& topElem != '{'){//栈空
                printf("%c ",topElem);
                Pop(s,topElem);//先打印后弹出
                GetTop(s,topElem);//@@@
            }

            Push(s,'+');
            break;
        case '-':
            GetTop(s,topElem);//弹出栈顶元素
            //栈中只能是左括号or运算符
            //若栈非空,且栈顶元素不是左括号, 对于+-,则无条件pop
            while(!StackEmpty(s) && topElem != '('&& topElem != '['&& topElem != '{'){
                printf("%c ",topElem);
                Pop(s,topElem);
                GetTop(s,topElem);//@@@
                //flag++;
            }
            //当前运算符号入栈
            Push(s,'-');
            break;
        case '*':
            GetTop(s,topElem);//弹出栈顶元素
             //若栈非空,且栈顶元素不是左括号, 对于*,则只有* / 优先级>= *
            while(!StackEmpty(s) && topElem != '('&& topElem != '['&& topElem != '{'){//
                if(topElem=='*'||topElem=='/'){//优先级>='*'的出栈
                    printf("%c ",topElem);
                    Pop(s,topElem);
                    GetTop(s,topElem);//@@@查看下一个栈顶元素是否需要弹出
                    continue;//@@@
                  }
                  break;//若优先级< '*',则直接跳出while
            }

            Push(s,'*');

            break;
        case '/':
            GetTop(s,topElem);//弹出栈顶元素
            //若栈非空,且栈顶元素不是左括号, 对于*,则只有* / 优先级>= /
            while(!StackEmpty(s) && topElem != '('&& topElem != '['&& topElem != '{'){
                if(topElem=='*'||topElem=='/'){
                    printf("%c ",topElem);
                    Pop(s,topElem);
                    GetTop(s,topElem);//@@@
                    continue;
                  }
                  break;//若优先级< '/',则直接跳出while
            }
            //将此运算符入栈
            Push(s,'/');
            break;
        }
    }

    while(!StackEmpty(s)){
        Pop(s,topElem);

        printf("%c ",topElem);
    }
    return true;
}

int main(){
    char str0[35]="((15/(7-(1+1)))*3)-(4+(4+8))";
    char str1[35]="A+B-c*D/e+f";
    char str2[35]="A+B*(c-D)-E/F";

    printf("中缀表达式: ");
    for(int i=0;i<strlen(str0);i++){
        printf("%c",str0[i]);
    }
    printf("\n后缀表达式:");
    midToSuffix(str0, strlen(str0));
    printf("\n");

    printf("\n*****************************\n\n");

    printf("中缀表达式: ");
    for(int i=0;i<strlen(str1);i++){
        printf("%c",str1[i]);
    }
    printf("\n后缀表达式:");
    midToSuffix(str1, strlen(str1));
    printf("\n");

    printf("\n*****************************\n\n");

    printf("中缀表达式: ");
    for(int i=0;i<strlen(str2);i++){
        printf("%c",str2[i]);
    }
    printf("\n后缀表达式:");
    midToSuffix(str2, strlen(str2));
    printf("\n");


    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值