中缀式转后缀式
给出一个中缀表达式,要求计算结果,往往需要先将中缀式转变成后缀式以方便计算。转换的主要步骤如下:
- 设立一个操作符栈,用以临时存储操作符;
- 从左到右扫描中缀式,如果是数字则直接输出;
- 如果是操作符x,则将其优先级与栈顶操作符进行比较,并遵照下列规则进行处理:
- 若x的优先级高于栈顶操作符,则压入操作符栈;
- 若x的优先级低于或等于栈顶操作符,则将栈中操作符不断出栈输出,直到x的优先级高于栈顶操作符;
- 若x为’(’,则直接压入栈中;
- 若x为’)’,则将栈中操作符不断出栈输出,直到栈顶为’(’。
- 重复上述步骤直到扫描完中缀表达式,若操作符栈不为空,则依次出栈输出直到空。
stack<char> op; // 操作符栈
map<char, int> priority; // 操作符优先级
void createPr() // 定义操作符优先级
{
priority['+'] = priority['-'] = 1;
priority['*'] = priority['/'] = 2;
}
void change(string s)
{
char x;
for (int i = 0; i < s.length(); i++) // 扫描中缀式
{
x = s[i];
if (x == ' ') // 空格跳过
continue;
else if (x <= '9' && x >= '0') // 数字直接输出
cout << x;
else if (x == '(') // 左括号直接压入
op.push(x);
else if (x == ')') // 右括号不断出栈直到遇到左括号
{
while (op.top() != '(')
{
cout << op.top();
op.pop();
}
op.pop();
}
else
{
while (!op.empty() && priority[x] <= priority[op.top()]) // 当前操作符优先级低于或等于栈顶操作符时不断出栈,直到优先级高于栈顶操作符
{
cout << op.top();
op.pop();
}
op.push(x);
}
}
while (!op.empty()) // 最后非空栈不断输出
{
cout << op.top();
op.pop();
}
}
以上只是直接转换为后缀式这一步,如果还需要进行后续计算,则应该用一个队列保存后缀式。对于该队列,从队首开始扫描,如果是操作数则压入操作数栈中;如果是操作符,则依次出栈操作数 x 2 x_2 x2和 x 1 x_1 x1(注意,先出栈的是第二操作数,后出栈的是第一操作数),进行计算,将生成的新数压入栈中。重复操作直到后缀式扫面完毕,最后栈中剩下的数即为计算结果。