前中后缀表达式定义,求值,及其相互转化
---恢复内容开始---
定义:(直接上例子了)
前缀表达式:
- × + 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、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。