C/C++的中缀转后缀并求值的实现
2016-11-14 21:09
337 查看
简单的中缀转后缀并求值的C/C++实现
中缀转后缀
Description
输入一个中缀算术表达式S,S中的操作数为0到9,只含+,-和*,/运算,也可能含有括号(),运算符的计算顺序和实际四则运算的计算顺序相同. 请输出与S等价的后缀表达式,注意输出结果不要含有多余的括号或空格.Input
输入有多组数据.每组数据是一个中缀表达式S,S的长度不超过50. 输入的S保证合法,而且不包含多余的空格或制表符.
输入以#号结束.
Output
对于每个中缀表达式,输出转换后的后缀表达式,每个输出占一行.Sample Input
11+2*3
(1-2)/3
#
Sample Output
1123*+
12-3/
话不多说,直接贴代码,具体分析见上一篇博客
#include <iostream> #include <stdlib.h> #include <string> #include <stack> using namespace std; bool isBetter(char a, char b) { if ((a == '*' || a == '/') && (b == '+' || b == '-')) return true; return false; } int main() { string input; while(1) { cin >> input; if (input[0] == '#') break; // 判断是否结束 int l = input.size(); stack<char> op; for (int i = 0; i <= l; i++) { if (i != l) { // 判断是否到达结尾 // 如果是数字,则直接输出 if (input[i] >= '0' && input[i] <= '9') { cout << input[i]; } else { // 如果栈为空或者是左括号,直接入栈 if (op.empty() || input[i] == '(') { op.push(input[i]); } else if (input[i] == ')'){ // 如果时右括号,则将栈输出,直到遇到一个左括号 while(!op.empty() && op.top() != '(') { cout << op.top(); op.pop(); } op.pop();// 将左括号弹出不输出 } else { // 如果是运算符,则比较其与栈顶运算符的优先级 while (!op.empty()) { if (isBetter(input[i], op.top())) { // 如果优先级高,则入栈 break; } else { // 如果优先级低,则输出栈顶,将当前运算符入栈 if (op.top() != '(') { // 确保栈顶不是左括号,左括号仅在读到右括号时处理 cout << op.top(); op.pop(); } else { break; } } } op.push(input[i]); // 将当前运算符入栈 } } } else { // 将剩下的操作符输出 while (!op.empty()) { cout << op.top(); op.pop(); } } } cout << endl; } return 0; }
计算中缀表达式的值
本题目将上面的转换封装为函数,并做了适当的处理以将不同的运算数分开Description
输入中缀算术表达式S,S中的操作数为非负整数,只含+,-和*,/运算,也可能含有括号(),运算符的计算顺序和实际四则运算的计算顺序相同. 输出表达式S的值. 注意除法运算只取整数部分,例如1/2=0.Input
输入有多组数据.每组数据是一个算术表达式S,S的长度不超过100. 输入的S保证合法,而且不包含多余的空格或制表符. S的操作数、中间结果和最终结果都不会超过int类型的范围,也不会出现除数为0的情况.
输入以#号结束.
Output
对于每个算术表达式S,输出S的值,每个输出占一行.Sample Input
1478+522
(478+522)*10
1/2-1
#
Sample Output
11000
10000
-1
#include <iostream> #include <stack> using namespace std; bool isBetter(char a, char b); string toPostifix(string input); int calculate(int x, int y, char t_op); int main() { string input, postfix; while (1) { // 运用后缀表达式,遇到数字是入栈,遇到运算符时,从栈中取出并弹出两个数进行运算,将其运算结果压入栈中 cin >> input; if (input[0] == '#') break; postfix = toPostifix(input); // 转成后缀表达式,用.将数字和操作符间隔开 int ll = postfix.size(); int tmpNum = 0; int mark = 0; // 用来标记是否输出是单个数字的情况 stack<int> num; for (int i = 0; i < ll; i++) { if (postfix[i] == '.') { // 如果读到. 则将读取到的数入栈 if (tmpNum != 0) { int x = tmpNum; num.push(x); tmpNum = 0; mark = 1; } } else { // 如果遇到的是数字,则逐步将其转成int if (postfix[i] >= '0' && postfix[i] <= '9') { tmpNum = tmpNum*10+postfix[i]-'0'; mark = 2; } else { // 遇到数字后面没有.而是操作符的情况下,也要将数字提取出来入栈 if (mark == 2) { int x = tmpNum; num.push(x); tmpNum = 0; mark = 1; } // 遇到运算符,计算出新的值,然后入栈 int num1 = num.top(); num.pop(); int num2 = num.top(); num.pop(); int ans = calculate(num2, num1, postfix[i]); num.push(ans); } } } if (mark == 2) { cout << tmpNum << endl; } else if (!num.empty()) { cout << num.top() << endl; } } return 0; } bool isBetter(char a, char b) { if ((a == '*' || a == '/') && (b == '+' || b == '-')) return true; return false; } int calculate(int x, int y, char t_op) { if (t_op == '+') return x+y; if (t_op == '-') return x-y; if (t_op == '*') return x*y; return x/y; } string toPostifix(string input) { string tmp = ""; int l = input.size(); stack<char> op; for (int i = 0; i <= l; i++) { if (i != l) { // 判断是否到达结尾 // 如果是数字,则直接输出 if (input[i] >= '0' && input[i] <= '9') { tmp += input[i]; } else { tmp += '.'; // 如果栈为空或者是左括号,直接入栈 if (op.empty() || input[i] == '(') { op.push(input[i]); } else if (input[i] == ')'){ // 如果时右括号,则将栈输出,直到遇到一个左括号 while(!op.empty() && op.top() != '(') { tmp += op.top(); op.pop(); } op.pop();// 将左括号弹出不输出 } else { // 如果是运算符,则比较其与栈顶运算符的优先级 if (isBetter(input[i], op.top())) { // 如果优先级高,则入栈 op.push(input[i]); } else { // 如果优先级低,则输出栈顶,将当前运算符入栈 if (op.top() != '(') { // 确保栈顶不是左括号,左括号仅在读到右括号时处理 tmp += op.top(); op.pop(); } op.push(input[i]); // 将当前运算符入栈 } } } } else { // 将剩下的操作符输出 while (!op.empty()) { tmp += op.top(); op.pop(); } } } return tmp; }
相关文章推荐
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 表达式求值,中缀后缀转换,表达式递归直接求值等相关算法的实现
- C++实现中缀表达式转后缀表达式并求值
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- #C++实现先中缀转后缀的算术表达式计算
- 线性表的实现与应用--表达式中缀转后缀并求值
- 多项式计算器-中缀变后缀并求值-C++版
- 算术表达式求值(中缀转后缀,后缀求值,java 栈实现)
- 中缀转后缀 c++实现
- 中缀表达式到后缀表达式的转换C++实现
- 利用栈实现的后缀形式的算术表达式的求值的c++程序
- windows下,c /c++实现磁盘扫描,结合配置文件,读取特定后缀文件目录代码
- 实现中缀整数表达式求值--使用数组实现,在数组头处一个栈,在数组尾部有另一个栈
- 接上篇文章的中缀与后缀的代码实现
- windows下,c /c++实现磁盘扫描,结合配置文件,读取特定后缀文件目录代码
- java实现 中缀转后缀
- 用C++实现表达式求值
- 数据结构_链表_稀疏多项式求值_C++实现
- 中缀转后缀表达式并求值
- 从文件夹中读取子文件夹内带有指定后缀如.bmp文件的C++实现,并读取子文件夹后缀数字