C/C++的中缀转后缀并求值的实现

来源:互联网 发布:sql商务系统开发培训 编辑:程序博客网 时间:2024/06/03 23:44

简单的中缀转后缀并求值的C/C++实现

中缀转后缀

Description

输入一个中缀算术表达式S,S中的操作数为0到9,只含+,-和*,/运算,也可能含有括号(),运算符的计算顺序和实际四则运算的计算顺序相同. 请输出与S等价的后缀表达式,注意输出结果不要含有多余的括号或空格.

Input

输入有多组数据.

每组数据是一个中缀表达式S,S的长度不超过50. 输入的S保证合法,而且不包含多余的空格或制表符.

输入以#号结束.

Output

对于每个中缀表达式,输出转换后的后缀表达式,每个输出占一行.

Sample Input

1
1+2*3
(1-2)/3
#

Sample Output

1
123*+
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 {                        // 如果是运算符,则比较其与栈顶运算符的优先级                        if (isBetter(input[i], op.top())) { // 如果优先级高,则入栈                            op.push(input[i]);                        } else { // 如果优先级低,则输出栈顶,将当前运算符入栈                            if (op.top() != '(') { // 确保栈顶不是左括号,左括号仅在读到右括号时处理                                cout << op.top();                                op.pop();                            }                            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

1
478+522
(478+522)*10
1/2-1
#

Sample Output

1
1000
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;}
0 0