【複雜運算式】
成績: 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;
}