Problem
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0
Sample Output
3.00
13.36
思路
中缀表达式转后缀,再求值即可
具体见:https://blog.csdn.net/Feynman1999/article/details/64912591
code
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
vector<string> ans;
vector<string> thought_opera = { "+", "-", "*", "/", "(", ")" };
short Priority[5] = { 0,0,1,1,-1 };
bool is_opera(string tp) {
if (tp == "+" || tp == "-" || tp == "*" || tp == "/" || tp == "(" || tp == ")") return true;
return false;
}
ll string_to_num(string tp) {
ll flag = 1;
if (tp[0] == '-') {
flag = -1;
tp = tp.substr(1);
}
ll num = 0;
for (int i = 0; i < tp.length(); ++i) {
num *= 10;
num += tp[i] - '0';
}
return flag * num;
}
int main()
{
//freopen("in.txt", "r", stdin);
string s;
while (getline(cin, s)) {
if (s == "0") break;
ans.clear();
stack<string> opera;
stringstream scin(s);
string tmp;
while (scin >> tmp)
{
if (is_opera(tmp)) {
if (tmp == ")") {
while (opera.top() != "(")//数据保证一定有(
{
ans.push_back(opera.top());
opera.pop();
}
opera.pop();//括号不用输出
}
else if (tmp == "(") {
opera.push(tmp);
}
else {
short id1 = find(thought_opera.begin(), thought_opera.end(), tmp) - thought_opera.begin();
while (!opera.empty())
{
short id2 = find(thought_opera.begin(), thought_opera.end(), opera.top()) - thought_opera.begin();
if (Priority[id1] <= Priority[id2]) {
ans.push_back(opera.top());
opera.pop();
}
else {
break;
}
}
opera.push(tmp);
}
}
else {
ans.push_back(tmp);// is number
}
}
while (!opera.empty())
{
ans.push_back(opera.top());
opera.pop();
}
//for (auto k : ans) {
// cout << k << " ";
//}
stack<double> number;//由逆波兰表达式求值
for (auto k : ans) {
if (is_opera(k)) {
double number1 = number.top();
number.pop();
double number2 = number.top();
number.pop();
if (k == "-") {
number.push(number2 - number1);
}
else if (k == "+") {
number.push(number2 + number1);
}
else if (k == "*") {
number.push(number2 * number1);
}
else {// "/"
number.push(number2 / number1);
}
}
else {
number.push(string_to_num(k));
}
}
printf("%.2f\n", number.top());
}
}