前中后缀表达式定义,求值,及其相互转化

---恢复内容开始---

定义:(直接上例子了)

前缀表达式:

- × + 3 4 5 6

运算符位于操作数之前。

中缀表达式:

(3 + 4) × 5 - 6

操作符以中缀形式处于操作数的中间。

后缀表达式:

3 4 + 5 × 6 -

运算符位于操作数之后。

表达式求值:

前缀表达式求值:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

代码如下:(前缀表达式之间用逗号分隔)

ps:代码没测

double solve(char *str){
    stack<dobule>dnum;
    int len=strlen(str);
    int cnt=0,idx;
    bool flag=true;
    for(int i=len-1;i>=0;i--){
        if(str[i]==','||i==0){
            if(i!=0) idx=i+1;
            else idx=i;
            if(str[idx]=='+'){
                if(cnt>=2){
                    int a=dnum.top();dnum.pop();
                    int b=dunm.top();dnum.pop();
                    dnum.push(a+b);
                }else{
                    flag=0;
                    break;
                }
            }else if(str[idx]=='-'){
                if(cnt>=2){
                    int a=dnum.top();dnum.pop();
                    int b=dnum.top();dnum.pop();
                    dnum.push(a-b);
                }else{
                    flag=0;
                    break;
                }
            }else if(str[idx]=='*'){
                if(cnt>=2){
                    int a=dnum.top();dnum.pop();
                    int b=dnum.top();dnum.pop();
                    dnum.push(a*b);
                }else{
                    flag=0;
                    break;
                }
            }else if(str[idx]=='/'){
                if(cnt>=2){
                    int a=dnum.top();dnum.pop();
                    int b=dnum.top();dnum.pop();
                    dnum.push(a/b);
                }else{
                    flag=0;
                    break;
                }
            }else if(str[idx]>='0'&&str[idx]<='9'){
                double sum=0.0;
                while(str[idx]!=','&&idx<len){
                    sum=sum*10+str[idx]-'0';
                    idx++;
                }
                dnum.push(sum);
                cnt++;
            }else{
                flag=0;
                brak;
            }
        }
    }
}
 

后缀表达式求值:从左到右扫描后缀表达式,若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的 放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果。代码类似前缀表达式求值;

中缀表达式求值:转换成前缀表达式或者后缀表达式后求值

中缀表达式转前缀表达式:

//首先设定一个操作符栈,从右到左顺序扫描整个中缀表达式,如果是操作数,则直接归入前缀表达式;
//如果是操作符,则检测器是否是右括号,如果是右括号,则直接将其入栈;
//如果是左括号,则将栈中的操作符依次弹栈,归入前缀表达式,直至遇到右括号,将右括号弹栈,处理结束;
//如果是其他操作符,则检测栈顶操作符的优先级与当前操作符的优先级关系,
//如果栈顶操作符优先级大于当前操作符的优先级,则弹栈,并归入前缀表达式,直至栈顶操作符优先级小于等于当前操作符优先级,这时将当前操作符压栈。
//当扫描完毕整个中缀表达式后,检测操作符栈是否为空,如果不为空,则依次将栈中操作符弹栈,归入前缀表达式。最后,将前缀表达式翻转,得到中缀表达式对应的前缀表达式。

中缀表达式转后缀表达式:

//1、从左至右扫描一中缀表达式。
//2、若读取的是操作数,则判断该操作数的类型,并将该操作数存入操作数堆栈
//3、若读取的是运算符
// (1) 该运算符为左括号"(",则直接存入运算符堆栈。
// (2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。
// (3) 该运算符为非括号运算符:
// (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。
// (b) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。
// (c) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈
//4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。

原文地址:https://www.cnblogs.com/imzscilovecode/p/8016941.html