Advertisement
zhangsongcui

Arithmetic formula

Mar 20th, 2011
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <stack>
  4. #include <sstream>
  5. #include <cmath>
  6. #include <map>
  7. #include <functional>
  8. #include <stdexcept>
  9.  
  10. using namespace std;
  11.  
  12. double Calculate(const string& expression, const map<char, pair<unsigned, function<double(double, double)>>>& Operators) throw(invalid_argument)
  13. {
  14.     stack<pair<double, signed char> > s;
  15.     double Result=0, newNum;
  16.     char oldOperator='\0', newOperator;
  17.     istringstream iss(expression);
  18.  
  19.     while (true)
  20.     {
  21.         if (!(iss >> newNum))
  22.         {
  23.             iss.clear();
  24.             if (iss.get()=='(')
  25.             {
  26.                 s.push(make_pair(Result, -oldOperator));
  27.                 oldOperator='\0';
  28.                 continue;
  29.             }
  30.             else
  31.                 throw invalid_argument("非法字符或语法错误");
  32.         }
  33. NEXT:
  34.         if (!(iss >> newOperator))
  35.             break;
  36.         if (Operators.find(newOperator)==Operators.end())
  37.         {
  38.             if (newOperator==')')
  39.             {
  40.                 Result=Operators.find(oldOperator)->second.second(Result, newNum);
  41.                 while (true)
  42.                 {
  43.                     if (s.empty())
  44.                         throw invalid_argument("括号不匹配,缺少左括号");
  45.                     if (s.top().second>0)
  46.                     {
  47.                         Result=Operators.find(s.top().second)->second.second(s.top().first, Result);
  48.                         s.pop();
  49.                     }
  50.                     else
  51.                     {
  52.                         oldOperator=-s.top().second;
  53.                         newNum=Result;
  54.                         Result=s.top().first;
  55.                         s.pop();
  56.                         goto NEXT;
  57.                     }
  58.                 }
  59.             }
  60.             else
  61.                 throw invalid_argument("非法运算符");
  62.         }
  63.         if (Operators.find(newOperator)->second.first>Operators.find(oldOperator)->second.first)
  64.         {
  65.             s.push(make_pair(Result, oldOperator));
  66.             Result=newNum;
  67.         }
  68.         else
  69.         {
  70.             Result=Operators.find(oldOperator)->second.second(Result, newNum);
  71.             if (Operators.find(newOperator)->second.first<Operators.find(oldOperator)->second.first)
  72.             {
  73.                 while (!s.empty() && s.top().second>0 && Operators.find(newOperator)->second.first<Operators.find(s.top().second)->second.first)
  74.                 {
  75.                     Result=Operators.find(s.top().second)->second.second(s.top().first, Result);
  76.                     s.pop();
  77.                 }
  78.             }
  79.         }
  80.         oldOperator=newOperator;
  81.     }
  82.  
  83.     Result=Operators.find(oldOperator)->second.second(Result, newNum);
  84.     while (!s.empty())
  85.     {
  86.         if (s.top().second<=0)
  87.             throw invalid_argument("括号不匹配,缺少右括号");
  88.         Result=Operators.find(s.top().second)->second.second(s.top().first, Result);
  89.         s.pop();
  90.     }
  91.     return Result;
  92. }
  93.  
  94. int main()
  95. {
  96.     string s;
  97.     map<char, pair<unsigned, function<double(double, double)>>> Operators;
  98.     {
  99.         Operators['+']=make_pair(1, plus<double>());
  100.         Operators['-']=make_pair(1, minus<double>());
  101.         Operators['*']=make_pair(2, multiplies<double>());
  102.         Operators['/']=make_pair(2, divides<double>());
  103.         Operators['^']=make_pair(3, [](double a, double b){return pow(a,b);});
  104.         Operators['\0']=make_pair(~0, [](double, double b){return b;});
  105.     }
  106.     while (getline(cin, s) && s.empty());
  107.     try
  108.     {
  109.         cout << Calculate(s, Operators) << endl;
  110.     }
  111.     catch (exception& e)
  112.     {
  113.         cerr << e.what() << endl;
  114.     }
  115.     return 0;
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement