计算中缀表达式是一个特别经典的关于栈的算法题,几乎全部的数据结构教材中都会涉及,并且不少公司面试或者笔试的时候会把这道题做为一个考点。所以,他的重要程度就不言而喻,下面 是关于表达式求值的一个总结。ios
题目: 输入一个中缀表达式计算表达式的结果。c++
输入的前提假设:面试
(1)只考虑+,-,*,/这四种运算符,中缀表达式只有一种括号:()。算法
(2)输入的中缀表达式只有整数,没有小数。数据结构
(3)假定输入是合法的。spa
为了按部就班,此处先讨论如何将中缀表达式转化为后缀表达式,在讨论如何计算后最表达式,在前二者的基础上,讨论如何直接计算中缀表达式的结果。对于上面各表达式的概念再也不赘述。.net
一.中缀表达式转化为后缀表达式code
中缀表达式转化为后缀表达式式须要一个临时栈S暂存运算符。blog
首先将各运算符的优先级排列,(数字越大优先级越高):get
1:(
2:+ -
3:* /
4.:)
对输入的中缀表达式从左到右遍历:
伪代码:
(1)若是遇到数字,直接添加到后缀表达式末尾。
(2)若是遇到+ - * /:
先判断栈是否为空。如果,则将此运算压入栈。若不是,则查看当前 栈顶元素。若栈顶元素的优先级大于或等于此操做符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式后面,并继续上面的判断。若是不知足上述的判断,或栈为空,将这个运算符入栈。
(3)若是遇到左括号,直接入栈。若是遇到右括号,弹出左括号前的全部操做符,并将左括号弹出。(右括号不如栈)
(4)字符遍历结束,若是栈不为空,则弹出栈中全部的操做符,将他们添加到后缀表达式的末尾,知道栈为空。
二.计算后缀表达式
伪代码: 准备一个数字栈,从左到右扫描表达式,若是是数字就入栈。若是是符号,从数字栈中弹出两个数字,第一个取出的数字为右运算数,第二个为左运算数,进行运算。而后将运算结果放入数字栈中,如此反复直到读完整个表达式,留在数字栈中的数字就是最终结果。
默认:输入的表达式中的全部的的数都是0——9的 整数,运算结果也为整数。
#include<bits/stdc++.h> using namespace std; int Get_Priority(char ch) { if(ch=='(') return 1; else if(ch=='-'||ch=='+') return 2; else if(ch=='*'||ch=='/') return 3; else return 4; } /* 中缀表达式转后缀表达式 */ string Get_Hou(string s) { stack<char>My_Stack; int size=s.size(); int i=0; string res="";///用于保存转化后的结果 char temp; while(i<size) { ///若为数字直接添加到后缀表达式的后面 if(s[i]>='0'&&s[i]<='9') { res.push_back(s[i]); } else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/') { if(My_Stack.empty())///若栈为空,直接将运算符进栈 { My_Stack.push(s[i]); } else///否者若栈顶的优先级大于或等于当前的优先级,重复出栈并加入到后缀表达式末尾 { while(!My_Stack.empty()) { temp=My_Stack.top(); if(Get_Priority(temp)>=Get_Priority(s[i])) { res.push_back(temp); My_Stack.pop(); } else break; } My_Stack.push(s[i]);///将当前运算符进栈 } } else { if(s[i]=='(') My_Stack.push(s[i]); ///若为作左括号直接进栈 else///不然,将栈中的元素所有出栈知道碰见左括号 { while(My_Stack.top()!='(') { temp=My_Stack.top(); res.push_back(temp); My_Stack.pop(); } My_Stack.pop();///删除左括号后缀表达式和前缀表达式不存在括号,位置即体现了优先级 } } i++; } ///遍历完后若栈非空弹出全部的元素 while(!My_Stack.empty()) { temp=My_Stack.top(); res.push_back(temp); My_Stack.pop(); } return res; } /* 计算后缀表达式 */ int calculate(string s) { stack<int>My_Stack; int size=s.size(); int num1,num2,num3; for(int i=0;i<size;i++) { if(s[i]>='0'&&s[i]<='9') { My_Stack.push(s[i]-'0'); } else { num2=My_Stack.top(); My_Stack.pop(); num1=My_Stack.top(); My_Stack.pop(); switch(s[i]) { case '+': num3=num1+num2; break; case '-': num3=num1-num2; break; case '*': num3=num1*num2; break; case '/': num3=num1/num2; break; } My_Stack.push(num3); } } return My_Stack.top(); } int main() { string s="1+(2-3)*4+4/2"; cout<<"中缀表达式:"<<endl<<s<<endl; string res=Get_Hou(s); cout<<"后缀表达式:"<<endl<<res<<endl; int num_res=calculate(res); cout <<"后缀表达式计算结果:"<< endl << num_res << endl; return 0; }
参考博客,此段代码摘自:https://blog.csdn.net/sinat_27908213/article/details/80273557
#include<iostream> #include<string> #include<stack> using namespace std; int getPriority(char ch) { //获取优先级 if (ch == '(') return 1; else if (ch == '+' || ch == '-') return 2; else if (ch == '*' || ch == '/') return 3; else return 4; } void calculate(stack<double> &mystack, char operation) { double num1, num2, num3; num2 = mystack.top(); mystack.pop(); num1 = mystack.top(); mystack.pop(); if (operation == '+') { num3 = num1 + num2; } else if (operation == '-') { num3 = num1 - num2; } else if (operation == '*') { num3 = num1 * num2; } else if (operation == '/') { num3 = num1 / num2; } mystack.push(num3); } double calculator(string str) { //计算中缀表达式,默认输入是合法的 stack<double> mystack_number; stack<char> mystack_operation; int i = 0, j; int size = str.size(); char tmp_operation; string tmp_num; while (i < size) { if (str[i] >= '0' && str[i] <= '9') { j = i; while (j < size && str[j] >= '0' && str[j] <= '9') { j++; } tmp_num = str.substr(i, j - i); mystack_number.push(atoi(tmp_num.c_str())); i = j; } else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') { if (mystack_operation.empty()) { mystack_operation.push(str[i]); } else { while (!mystack_operation.empty()) { tmp_operation = mystack_operation.top(); if (getPriority(tmp_operation) >= getPriority(str[i])) { //计算 calculate(mystack_number, tmp_operation); mystack_operation.pop(); } else break; } mystack_operation.push(str[i]); } i++; } else { if (str[i] == '(') mystack_operation.push(str[i]); else { while (mystack_operation.top() != '(') { tmp_operation = mystack_operation.top(); //计算 calculate(mystack_number, tmp_operation); mystack_operation.pop(); } mystack_operation.pop(); } i++; } } //遍历完后,若栈非空,弹出全部元素 while (!mystack_operation.empty()) { tmp_operation = mystack_operation.top(); //计算 calculate(mystack_number, tmp_operation); mystack_operation.pop(); } return mystack_number.top(); } int main() { string str = "1+(2-3)*4+10/2+2*2+2+2/5"; cout << "中缀表达式为:" << endl << str << endl; double num_res = calculator(str); cout << "计算结果:" << endl << num_res << endl; system("pause"); return 0; }