考虑到竞赛时,可能会有出到表达式计算,所以这篇博客就是给一个表达式,先求出后缀表达式,再求值的板子。
在PTA平台上的 7-20 表达式转换 (25 分) 7-21 求前缀表达式的值 (25 分)测试通过。
可以处理正负号和小数点。
input:
2.3+3*(-4+7)+8/4
output:
13.3
Code:
#include <bits/stdc++.h>
using namespace std;
map<string, int>mp;
string s, t;
stack<string>st;
vector<string>ans;
stack<double>shu;
int main()
{
mp["+"] = 1;
mp["-"] = 1;
mp["*"] = 2;
mp["/"] = 2;
mp["("] = 3;
cin >> s;
for (int i = 0; i < s.size();)
{
//右边的判断处理正负号
if (isdigit(s[i]) || ((s[i] == '-' || s[i] == '+') && (i == 0 || (i != 0 && (!isdigit(s[i - 1]) && s[i - 1] != ')')))))
{
t.clear();
//以下5行处理正负号
if (s[i] == '-' || s[i] == '+')
{
if (s[i] == '-')
t = s[i];
i++;
}
//处理小数点
while (isdigit(s[i]) || s[i] == '.')
{
t += s[i];
i++;
}
ans.push_back(t);
}
else
{
t = s[i];
if (t == ")")
{
while (true)
{
if (st.top() == "(")
{
st.pop();
break;
}
else
{
ans.push_back(st.top());
st.pop();
}
}
}
else
{
while (!st.empty())
{
if (mp[st.top()] < mp[t] || st.top() == "(")
break;
else
{
ans.push_back(st.top());
st.pop();
}
}
}
if (t != ")")
st.push(t);
i++;
}
}
while (!st.empty())
{
ans.push_back(st.top());
st.pop();
}
/*
for (int i = 0; i < ans.size(); i++)
{
cout << ans[i];
printf("%c", i == ans.size() - 1 ? '\n' : ' ');
}
*/
//ans是后缀表达式
for (int i = 0; i < ans.size(); i++)
{
if (ans[i].size() > 1 || isdigit(ans[i][0]))
{
bool flag = false, flag2 = false;
double zhen = 0, xiao = 0, bas = 0.1;
if (ans[i][0] == '-')
flag = true;
for (int j = 0; j < ans[i].size(); j++)
{
if (ans[i][j] == '-')
continue;
if (ans[i][j] == '.')
{
flag2 = true;
continue;
}
if (flag2 == false)
zhen = zhen * 10 + ans[i][j] - '0';
else
{
xiao += (ans[i][j] - '0') * bas;
bas *= 0.1;
}
}
if (flag == false)
shu.push(zhen + xiao);
else
shu.push(-zhen - xiao);
}
else
{
double num1, num2, sol;
num2 = shu.top();
shu.pop();
num1 = shu.top();
shu.pop();
switch (ans[i][0])
{
case '+':
sol = num1 + num2;
break;
case '-':
sol = num1 - num2;
break;
case '*':
sol = num1 * num2;
break;
case '/':
sol = num1 / num2;
break;
}
shu.push(sol);
}
}
printf("%.1lf", shu.top());
}