v 0. Pasted by slipstak2 as cpp at 2011-01-22 14:14:32 MSK and set expiration to never.

Paste will expire never.

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <cmath>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. enum LexType {PLS,MNS,MUL,DIV,OPN,CLS,NUM,FNC,END,NAN};
  10. string tSymbols = "+-*/()";
  11.  
  12. string expStr;              // первоначальное арифметическое выражение
  13. int expPos;             // текущая позиция выражения
  14. LexType curLex = NAN;   // тип текущей лексемы
  15. string lexVal;          // значение текущей лексемы
  16.  
  17.  
  18. const int funcCount = 2;
  19. string funcsName[] = {"sin","cos"};
  20. double (*pfunc[])(double) = {&sin, &cos};
  21.  
  22. void input() {
  23.     getline(cin,expStr);
  24. }
  25. bool isNum(const string &str) {
  26.    
  27.     for (int i=0;i<str.size();i++) {
  28.         if (!isdigit(str[i]) && str[i]!='.')
  29.             return false;
  30.     }
  31.     return count(str.begin(), str.end(),'.')<=1;
  32. }
  33. double toNum(string &str) {
  34.     double res;
  35.     sscanf(str.c_str(), "%lf", &res);
  36.     return res;
  37. }
  38. bool isFunc(const string &str) {
  39.     for (int i=0;i<funcCount;i++) {
  40.         if (str == funcsName[i])
  41.             return true;
  42.     }
  43.     return false;
  44. }
  45. int FuncPos(const string &str) {
  46.     for (int i=0;i<funcCount;i++) {
  47.         if (str == funcsName[i])
  48.             return i;
  49.     }
  50.     return -1;
  51. }
  52. bool isSep(const char c) {
  53.     return tSymbols.find(c) != -1 || c == ' ';
  54. }
  55. void nextLex(LexType &curLex) {
  56.     while (expPos < expStr.size() && expStr[expPos] == ' ')
  57.         expPos++;
  58.     if (expPos == expStr.size())
  59.         curLex = END;
  60.     else {
  61.         char c = expStr[expPos];
  62.         int pos = tSymbols.find(c);
  63.         if (pos != -1) {
  64.             curLex = (LexType)pos;
  65.             expPos++;
  66.         }
  67.         else {
  68.             // либо функция, либо число
  69.             lexVal.clear();
  70.             while (expPos < expStr.size() && !isSep(expStr[expPos]))
  71.                 lexVal += expStr[expPos++];
  72.             if (isNum(lexVal))
  73.                 curLex = NUM;
  74.             else if (isFunc(lexVal))
  75.                 curLex = FNC;
  76.             else
  77.                 curLex = NAN;
  78.         }
  79.     }
  80. }
  81. bool calcExp(double &res);
  82. bool calcFunc(double &res) {
  83.     // <Функция> = <ИмяФункции>(<Выражение>)
  84.     string funcName = lexVal;
  85.     nextLex(curLex);
  86.     if (curLex != OPN)
  87.          return false;
  88.     nextLex(curLex);
  89.     double arg =0.0;
  90.     if (!calcExp(arg))
  91.         return false;
  92.     res = pfunc[FuncPos(funcName)](arg);
  93.     return true;
  94. }
  95. bool calcMul(double &res) {
  96.     // <Множитель> = +|- <ДробноеЧисло>|<Функция>|(<Выражение>)
  97.     bool isNeg = false;
  98.     if (curLex == PLS || curLex == MNS) {
  99.         isNeg = curLex == MNS;
  100.         nextLex(curLex);
  101.     }
  102.     switch(curLex) {
  103.         case NUM:
  104.             {
  105.                 res = toNum(lexVal);
  106.                 nextLex(curLex);
  107.                 break;
  108.             }
  109.         case FNC:
  110.             {
  111.                 if (!calcFunc(res))
  112.                     return false;
  113.                 if (curLex != END)
  114.                     nextLex(curLex);
  115.                 break;
  116.             }
  117.         case OPN:
  118.             {
  119.                 nextLex(curLex);
  120.                 if (!calcExp(res))
  121.                     return false;
  122.                 if (curLex != CLS)
  123.                     return false;
  124.                 nextLex(curLex);
  125.                 break;
  126.             }
  127.         default : return false;
  128.     }
  129.     res *= isNeg ? -1 : 1;
  130.     return true;
  131. }
  132. bool calcTerm(double &res) {
  133.     // <Слагаемое> = <Множитель>{*|/<Множитель>}
  134.     if (!calcMul(res))
  135.         return false;
  136.     while (curLex == MUL || curLex == DIV) {
  137.         LexType oper = curLex;
  138.         double next = 0.0;
  139.         nextLex(curLex);
  140.         if (!calcMul(next))
  141.             return false;
  142.         switch(oper) {
  143.             case MUL: res *= next; break;
  144.             case DIV: res /= next; break; // DIV 0 запрещен по условию
  145.         }
  146.     }
  147.     return true;
  148. }
  149. bool calcExp(double &res) {
  150.     // <Выражение> = <Слагаемое>{+|-<Слагаемое>}
  151.     if (!calcTerm(res))
  152.         return false;
  153.     while (curLex == PLS || curLex == MNS) {
  154.         LexType oper = curLex;
  155.         nextLex(curLex);
  156.         double next = 0.0;
  157.         if (!calcTerm(next))
  158.             return false;
  159.         switch(oper) {
  160.             case PLS: res += next; break;
  161.             case MNS: res -= next; break;
  162.         }
  163.     }
  164.     return curLex == END || curLex == CLS;
  165. }
  166. void solve() {
  167.  
  168.     nextLex(curLex);
  169.     double res = 0.0;
  170.     if (calcExp(res))
  171.         printf("%0.3f", res);
  172.     else
  173.         printf("Error");
  174.        
  175. }
  176. int main() {
  177.     freopen("input.txt","r",stdin);
  178.     freopen("output.txt","w",stdout);
  179.     input();
  180.     solve();
  181.     return 0;
  182. }


Editing is locked.