【複雜運算式】
成績: 20 / 倒扣: 0.8
問題描述:
複雜運算式可有n個運算子(operator_1..operator_n),及m個運算元(operand_1.. operand_m),1 ≤ n ≤ 30,1 ≤ m ≤ 30,運算元可能是四則運算子(+、-、*、/ )及左右括號,運算元為可以有小數點的正數,例如:(10+ 22.2 )/ 5。請寫一個能夠算出複雜運算式結果的c++程式。
輸入說明:
程式的輸入有k行運算式,1 ≤ k ≤ 30,代表k組測試資料。每一行組輸入一個複雜運算式,運算子與運算元中間不一定有空格隔開。
輸出說明:
輸出運算式的結果到小數點後二位,算式中如果有除以0則輸出NA。
【輸入範例】 | 【輸出範例】 |
(100 + 20.2) * 10-5 15 / 0 + 3 | 1197.00 NA |
#include<iostream>
#include<string>
#include<sstream>
#include<cstdlib>
#include<iomanip>
#define MAX 80
using namespace std;
void inToPostfix(string*, double&);
int priority(string);
double eval(string*);
double cal(string, double, double);
int main()
{
int j, a;
double sum;
string str, sstr, target = "()+-*/";
unsigned i, pos;
while (getline(cin, str))
{
string infix[MAX] = { "" };
a = 0;
j = 0;
sum = 0;
i = pos = 0;
while ((i = str.find_first_of(target, pos)) != string::npos)
{
str.insert(i + 1, " ");
str.insert(i, " ");
pos += 3;
}
stringstream ss(str);
while (ss >> sstr)
{
infix[j] = sstr;
j++;
}
for (int k = 0; k < j; k++)
{
if (infix[k] == "/" && infix[k + 1] == "0")
a = 1;
}
if (a == 0)
{
inToPostfix(infix, sum);
}
if (a == 0)
cout << fixed << setprecision(2) << sum << endl;
else
cout << "NA" << endl;
}
return 0;
}
void inToPostfix(string *infix, double &sum)
{
string stack[MAX] = { "" }, postfix[MAX] = { "" };
int i, j, top;
i = 0;
j = 0;
top = 0;
while (infix[i] != "")
{
if (infix[i] == "(")
{
stack[++top].clear();
stack[top] = infix[i];
}
else if (infix[i] == "+" || infix[i] == "-" || infix[i] == "*" || infix[i] == "/")
{
while (priority(stack[top]) >= priority(infix[i]))
{
postfix[j].clear();
postfix[j++] = stack[top--];
}
stack[++top].clear();
stack[top] = infix[i];
}
else if (infix[i] == ")")
{
while (stack[top] != "(")
{
postfix[j].clear();
postfix[j++] = stack[top--];
}
top--;
}
else
{
postfix[j].clear();
postfix[j++] = infix[i];
}
i++;
}
while (top > 0)
{
postfix[j].clear();
postfix[j++] = stack[top--];
}
sum = eval(postfix);
}
int priority(string op)
{
if (op == "+" || op == "-")
return 1;
else if (op == "*" || op == "/")
return 2;
else
return 0;
}
double eval(string *postfix)
{
double stack[MAX] = { 0 };
string opnd[2] = { "" };
int top, i;
i = top = 0;
while (postfix[i] != "")
{
if (postfix[i] == "+" || postfix[i] == "-" || postfix[i] == "*" || postfix[i] == "/")
{
stack[top - 1] = cal(postfix[i], stack[top - 1], stack[top]);
top--;
}
else
{
opnd[0].clear();
opnd[0] = postfix[i];
stack[++top] = atof(opnd[0].c_str());
}
i++;
}
return stack[top];
}
double cal(string op, double p1, double p2)
{
if (op == "+")
return p1 + p2;
else if (op == "-")
return p1 - p2;
else if (op == "*")
return p1 * p2;
else if (op == "/")
return p1 / p2;
}