后缀表达式的计算原理
规则:
从左到右遍历表达式的每个数字和符号,遇到的是数字就进栈,遇到的是符号,就将栈顶的两个数字依次出栈,进行运算(运算规则:后出栈的数字1 符号 后出栈的数字2 ),再将运算结果进栈,知道获得最终结果。
样例:
后缀表达式例子:9 3 1 - 3 * + 10 2 / +
计算过程:
- 数字9入栈
- 数字3入栈
- 数字1入栈
- 遇到了 - 运算符,,这时候计算 3 - 1 = 2(注意数字的顺序,谁是减数,谁是被减数),数字2入栈
- 数字3入栈
- 遇到了运算符 * 。计算 2 * 3 = 6 ,数字6入栈
- 遇到了运算符 + 。9 + 6 = 15 .数字15入栈
- 数字10入栈
- 数字2入栈
- 遇到了运算符 / 。计算10 / 2 = 5,数字5入栈
- 遇到了运算符 + 。计算15 + 5 = 20.入栈。到这时遍历结束。最后栈中剩余一个数字20.
代码思路
- 首先采取函数传参的过程来解决这个问题,下面的代码采用传入一个要计算的字符串来解决问题
- 使用了STL封装好的stack栈
- 使用了string容器中的find_first_of()函数来查找,不懂的可以去先去百度了解了解这个函数
- 使用了函数库里面的stod函数,这个函数可以把一个字符串转换成一个double类型的浮点数
- 整体思路就是遍历传入的字符串(中间含有空格,把每个数字和运算符隔开了),从左向右进行遍历,具体看代码
C++代码实现
#include<iostream> #include<string> #include<stack> using namespace std; //后缀表达式计算函数 double calculate(const string str) { stack<double> mystack;//用来存数据 string Empty = " "; string ch = "+-*/"; string numbers = "0123456789"; string s = "0123456789+-*/"; int start, end; double num, secnodnum, firstnum; for (int i = 0; i < str.length(); ) { start = str.find_first_of(s, i);//查找第一个数字或者运算符 end = str.find_first_of(Empty, i);//查找第一空格 if (end == -1)//处理最后一个符号后没有空格的问题 { end = str.length(); } string tempstr = str.substr(start, end - start);//取出这一个元素 if ((tempstr == "+") || (tempstr == "-") || (tempstr == "*") || (tempstr == "/")) { secnodnum = mystack.top();//取出栈顶元素 mystack.pop();//出栈 firstnum = mystack.top();//取出栈顶元素 mystack.pop();//出栈 if (tempstr == "+") { num = firstnum + secnodnum; mystack.push(num); } if (tempstr == "-") { num = firstnum - secnodnum; mystack.push(num); } if (tempstr == "*") { num = firstnum * secnodnum; mystack.push(num); } if (tempstr == "/") { num = firstnum / secnodnum; mystack.push(num); } } else { double temp = stod(tempstr); mystack.push(temp); } i = end + 1;//控制下标的移动 } return mystack.top(); } int main() { string str; getline(cin, str); double ans = calculate(str);//记录后缀表达式运算的结果 cout << ans << endl; return 0; }
注意:上面的代码计算的是后缀表达式,而且函数的参数是一个字符串,字符串最后面并没有空格,如果有空格,把上面第20行-23的代码注释掉可以。
如果想了解怎样实现中缀表达式转后缀表达式,可以点击下面的链接