我们对表达式进行计算,关键是如何整理运算符的顺序,我们对每个运算符设定了一个值。
栈外运算符的值比栈内的值大的 就能压下去,栈外运算符的值比较小不能压下去,要把栈内的元算符Pop出来,然后再比较大小。
同一个运算符栈内的值要比栈外的值大,这样就能保证让同层次的运算符压不进去,让栈内的运算符先运算。
/******************************************************************************************************************
* Copyright (C): 随便copy....遵守那个啥GPL协议什么的
* @file : main.cpp
* @brief : 实现数据结构中栈在表达式求值
* @autor : mikkkkk
* @date : 2021/5/4 祝五四青年节快乐
******************************************************************************************************************/
#include <iostream>
#include <stack>
#include <map>
/*
*
* 1. 需要两个栈 一个map
*
* 2. 边输入 边计算 直接根据输入的决定 压入哪个栈
*
* 例子1:
* 输入 1-(1/2)#
* 输出 # (最开头的那个 #)
* 0.5 (答案)
* 例子2:
* 输入 1*2*(5-6)+1#
* 输出 #
* -1
* note: 输入的时候 数字只能输入 整数,感觉有待改进...
*
* */
using namespace std;
double calulate(double Tem1, double Tem2, char Opr)
{
switch (Opr)
{
case '+':
return Tem1 + Tem2;
case '-':
return Tem1 - Tem2;
case '*':
return Tem1 * Tem2;
case '/':
return Tem1 / Tem2;
}
}
int main()
{
//optr 是运算符 opnd是数字
stack<char> OPTR;
stack<double> OPND;
//RankIsp 栈内排名 ,RankIcp 栈外排名
map<char, int> RankIsp, RankIcp;
//在最头的位置 加 # ,和最后结束时的 # 对应。
OPTR.push('#');
//栈外对运算符的赋值
RankIcp.insert(std::pair<char, int>('#', 0));
RankIcp.insert(std::pair<char, int>('(', 6));
RankIcp.insert(std::pair<char, int>('*', 4));
RankIcp.insert(std::pair<char, int>('/', 4));
RankIcp.insert(std::pair<char, int>('+', 2));
RankIcp.insert(std::pair<char, int>('-', 2));
RankIcp.insert(std::pair<char, int>(')', 1));
//栈内对运算符的赋值
RankIsp.insert(std::pair<char, int>('#', 0));
RankIsp.insert(std::pair<char, int>('(', 1));
RankIsp.insert(std::pair<char, int>('*', 5));
RankIsp.insert(std::pair<char, int>('/', 5));
RankIsp.insert(std::pair<char, int>('+', 3));
RankIsp.insert(std::pair<char, int>('-', 3));
RankIsp.insert(std::pair<char, int>(')', 6));
while (1)
{
char temp;
cin >> temp;
if (temp == '+' || temp == '-' || temp == '/' || temp == '*' \
|| temp == '(' || temp == ')' || temp == '#')
{
//下面判断栈内和栈外的比如 如果栈外的大 就进去
while (1)
{
if (RankIcp[temp] > RankIsp[OPTR.top()])
{
OPTR.push(temp);
break;
} else if (RankIcp[temp] == RankIsp[OPTR.top()])
{
if (temp == '#') break;
if (temp == ')')
{
OPTR.pop();
break;
}
} else
{
double temp1, temp2, ans;
char Opr;
temp1 = OPND.top();
OPND.pop();
temp2 = OPND.top();
OPND.pop();
Opr = OPTR.top();
OPTR.pop();
//注意是前面的那个数字 对后面的数字的计算
ans = calulate(temp2, temp1, Opr);
OPND.push(ans);
continue;
}
}
} else
{ //这一步得到只是整数,所以只有整数push进操作数栈内,才能保证运算正确
OPND.push((double) temp - 48);
}
if (temp == '#')
break;
}
while (!OPTR.empty())
{
cout << OPTR.top();
OPTR.pop();
}
cout << endl;
while (!OPND.empty())
{
cout << OPND.top();
OPND.pop();
}
}