题目:
emmm,说实话呀,昨天我就做到这题了,看了好几遍也没读懂题目意思,然后参考的大神的博客,算是解出来了吧。大神博客:https://blog.csdn.net/fengzhanghao23/article/details/48493757
本题的大致意思就是利用栈求一个算术表达式的值,这里我是参考网上的代码,即使用中缀表达式求算法表达式的值。
例如表达式:(1+2)*3/(2-1)
解题思路:
开始扫描表达式
1、若token是”+“,”-“,”*“,”/“
符号栈为空,token直接压入符号栈中
符号栈不空,则比较token和符号栈栈顶符号的优先级。若token的优先级高,则token进符号栈。否则弹出符号栈栈顶元素以及操作数进行计算直至符号栈栈顶符号的优先级低于token,然后将token压栈
2、若token是”(“,直接压入符号栈中
3、若token是“)”,则弹出符号栈的栈顶符号以及操作数进行计算直至符号栈的栈顶元素为“)”停止,最后将“)”也弹出栈中,表示一对括号()里面的表达式计算完成
4、计算表达式的值,直至符号栈为空为止,表示式子全部计算完成,返回数字栈的栈顶元素即可。
关于中缀表达式,可参考:https://www.cnblogs.com/dolphin0520/p/3708602.html
写的很好,看了都能懂,强烈安利安利,看了作者好几篇博客,写真心不错,膜一下。
然后下面是自己参照大神的代码写的:
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;
int priority(string opt)/*操作符优先级*/
{
int p = 0;
if ("(" == opt)
return p = 1;
if ("+" == opt || "-" == opt)
return p = 2;
if ("*" == opt || "/" == opt)
return p = 3;
return p;
}
void calculate(stack<int> &opdstack, string opt)/*计算操作数栈的结果*/
{
if (opt == "+")
{
int a = opdstack.top(); //取栈顶元素a
opdstack.pop(); //弹出a
int b = opdstack.top(); //取栈顶元素b
opdstack.pop(); //弹出b
opdstack.push(a+b); //压入a+b的值
}
if (opt == "-")
{
int a = opdstack.top(); //取栈顶元素a
opdstack.pop(); //弹出a
int b = opdstack.top(); //取栈顶元素b
opdstack.pop(); //弹出b
opdstack.push(b - a); //压入b-a的值
}
if (opt == "*")
{
int a = opdstack.top(); //取栈顶元素a
opdstack.pop(); //弹出a
int b = opdstack.top(); //取栈顶元素b
opdstack.pop(); //弹出b
opdstack.push(a * b); //压入a*b的值
}
if (opt == "/")
{
int a = opdstack.top(); //取栈顶元素a
opdstack.pop(); //弹出a
int b = opdstack.top(); //取栈顶元素b
opdstack.pop(); //弹出b
opdstack.push(b / a); //压入b/a的值
}
}
int calcuExpression(vector<string> vec)/*计算表达式的值*/
{
stack<int> stack_opd; //操作数栈
stack<string> stack_opt; //操作符栈
for (unsigned i = 0; i != vec.size(); ++i)
{
string token = vec[i];
if (token == "+" || token == "-" || token == "*" || token == "/")
{
if (stack_opt.size() == 0) //操作符栈为空
stack_opt.push(token);
else
{
int token_p = priority(token);//该操作符的优先级等级
string top_opt = stack_opt.top();//获取操作栈栈顶操作符
int opt_p = priority(top_opt);//栈顶操作符的优先等级
if (token_p > opt_p)//当前操作符的优先级大于栈顶操作符的优先级
stack_opt.push(token);
else
{
while (token_p <= opt_p)//直至当前操作符大于栈顶操作符优先级
{
stack_opt.pop();//栈顶操作符出栈
calculate(stack_opd, top_opt);//计算操作数栈中两个元素的值
if (stack_opt.size() > 0)
{
top_opt = stack_opt.top();//更新栈顶操作符
opt_p = priority(top_opt); //更新操作符优先级
}
else
break;
}
stack_opt.push(token);//将当前操作符压出操作符栈
}
}
}
else if (token == "(")//左括号进操作符栈
stack_opt.push(token);
else if (token == ")")//匹配到最近的一个右括号
{
while (stack_opt.top() != "(")//计算()内的值,直至遇到"("退出
{
string top_opt = stack_opt.top();
calculate(stack_opd, top_opt);
stack_opt.pop();
}
stack_opt.pop();//弹出左括号,表示了计算一对括号里面的值
}
else
stack_opd.push(atoi(token.c_str()));//将string转换为数字
}
while (stack_opt.size() != 0)//直至符号栈栈为空
{
string top_opt = stack_opt.top();
calculate(stack_opd, top_opt);
stack_opt.pop();
}
return stack_opd.top();
}
int main(void)
{
vector<string> tokens = { "(","1","+","3",")","*","3","/","(","2","-","1",")" };
for (auto i = 0; i != tokens.size(); ++i)
cout << tokens[i];
cout << endl;
cout << calcuExpression(tokens) << endl;
return 0;
system("pause");
}
运行结果: