1. 中缀表达式转后缀表达式
① 两条基本规则: (1)数字无条件输出
(2)符号进栈进行相应处理
② 符号处理规则:
(简单点记忆就是,只有最强的才能站在高峰,不够强的,原先的大佬们就要跑路了,携款潜逃,等大佬都跑光了,才能压制住手下一帮小弟)
(1)当前符号的优先级 大于 栈顶符号的优先级时, 当前符号压栈
例:当前符号 * ,栈顶符号 + ,压栈
*(栈顶) |
+(原栈顶) |
(2)当前符号的优先级 小于等于 栈顶符号的优先级时,先将栈中元素弹出,直到当前栈顶的优先级 小于 待处理的符号的优先级。输入待处理符号为 -
优先级关系: * == / > + == -
原来的栈 | h后来的栈 |
* | |
+ | - |
③ 括号处理
(1) 左括号 ( 无条件压栈;
(2)右括号 ) 从栈顶开始向下逐个匹配左括号,匹配到了就将这一对括号之间的所有符号依次出栈。
④ 其他的补充:
2. 后缀表达式的计算
上述的处理将后缀表达式存储在一个数组当中。
规则:从左到右地扫描,
(1)操作数(数字)无条件压栈
(2)遇到操作码(符号)则从栈里弹出两个数字(先弹出的是第二操作数,后弹出的是第一操作数)
因为除法会产生小数,最好用浮点数的形式存储操作数。
(代码撸出来啦( ̄︶ ̄)↗ ,大家借鉴参考着用吧(●'◡'●))
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <cstdio>
using namespace std;
map<char, int> prior;
struct NUM
{
bool flag; // true---num false---operator
double number;
char opera;
};
bool isNum(char c)
{
if (c >= '0' && c <= '9')
return true;
else
return false;
}
void infix_to_postfix(vector<NUM> &v, string s)
{
stack<char> op; // for operator
NUM str_num;
for (int i = 0; i < s.size();)
{
if (isNum(s[i])) {
str_num.flag = true;
str_num.number = s[i] - '0';
i++;
while (isNum(s[i])) {
double num_temp = s[i] - '0';
str_num.number = str_num.number * 10 + num_temp;
i++;
}
v.push_back(str_num);
}
else
{ // 压栈
if (op.empty() || (prior[op.top()] < prior[s[i]]) || (s[i] == '('))
op.push(s[i]);
else
{
// 栈中符号都弹完或者出现了比当前符号等级还小的符号,终止弹出操作
while (!op.empty() && ( (prior[op.top()] >= prior[s[i]]) || (s[i]==')') ) )
{
char temp = op.top();
if (temp == '(') { // 匹配到最近的左括号终止弹出操作
op.pop();
break;
}
str_num.flag = false;
str_num.opera = temp;
v.push_back(str_num);
op.pop();
}
if(s[i]!=')') //防止再把右括号压入栈
op.push(s[i]);
}
i++;
}
}
// pop all the rest operator in stack
while (!op.empty())
{
char temp = op.top();
str_num.flag = false;
str_num.opera = temp;
v.push_back(str_num);
op.pop();
}
}
// 符号计算—— num1 op num2
double cal_op(char op, double num1, double num2)
{
if (op == '+')
return num1 + num2;
else if (op == '-')
return num1 - num2;
else if (op == '*')
return num1*num2;
else if (op == '/')
return num1 / num2;
cout << "未识别的计算,请自行完成(●'◡'●)" << endl;
return 0;
}
// 计算后缀表达式的值——讲真计算一个表达式的值,计算机还是后缀表达式更简单ε=( o`ω′)ノ
double calculate_postfix(vector<NUM> &v)
{
stack<double> num; // place the number
for (int i = 0; i < v.size(); ++i)
{
if (v[i].flag)
num.push(v[i].number);
else
{
double num2 = num.top(); num.pop();
double num1 = num.top(); num.pop();
num1 = cal_op(v[i].opera, num1, num2);
num.push(num1); // 结果压栈,有可能还有后续计算
}
}
return num.top();
}
int main(int argc, char const *argv[])
{
string input;
vector<NUM> result;
prior['*'] = prior['/'] = 2;
prior['+'] = prior['-'] = 1;
cin >> input;
infix_to_postfix(result, input);
cout << "postfix" << endl;
for (int i = 0; i < result.size(); ++i)
{
// cout << result[i].flag << " ";
if (result[i].flag)
cout << result[i].number << " ";
else
cout << result[i].opera << " ";
}
double cal_num = calculate_postfix(result);
cout << endl << "calculate result: " << cal_num << endl;
return 0;
}
运行出来的结果是这样的: