Advertisement
montimaj

CALCULATOR

May 1st, 2014
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.56 KB | None | 0 0
  1. #include<iostream>
  2. #include<stack>
  3. #include<string>
  4. #include<stdexcept>
  5. #include<cctype>
  6. #include<cmath>
  7. #include<vector>
  8. #include<utility>
  9. class functions
  10. {
  11. public:
  12.   static const std::string unary_func[];  
  13.   static const std::string binary_func[];  
  14. };
  15. const std::string functions::unary_func[] = {"sin", "cos", "tan", "log", "ln", "sqrt","exp"};
  16. const std::string functions::binary_func[]={"pow","abs"};
  17. int precedence(char op)
  18. {
  19.   if (op=='('  || op == ')')
  20.     return -2;
  21.   else if (op == ',')
  22.     return -1;
  23.   else if (op=='+' || op=='-')
  24.     return 1;
  25.   else if (op=='*' || op=='/' || op == '%')
  26.     return 2;  
  27.   return 0;
  28. }
  29. std::string modify_str(std::string s)
  30. {
  31.   std::string s1;
  32.   int len = s.length();
  33.   for (int i = 0;i<len;++i)
  34.   {
  35.     if(s[i] == ' ')
  36.       continue;
  37.     while (!precedence(s[i]) && i<len)
  38.     {
  39.       s1.push_back(std::tolower(s[i++]));
  40.       if (s[i] == ' ')
  41.         break;
  42.     }
  43.     if (s[i] != ' ')
  44.     {
  45.       s1.push_back(' ');
  46.       s1.push_back(s[i]);
  47.       s1.push_back(' ');
  48.     }    
  49.   }
  50.   return s1;
  51. }
  52. bool check_braces_comma(std::string s)
  53. {
  54.   int c1 = 0, c2 = 0,len = s.length(), p;
  55.   if (s[len-1] == '(')
  56.     return false;  
  57.   for (int i = 0;i<len;++i)
  58.   {
  59.     if (s[i] == '(')
  60.     {
  61.       c1++;
  62.       p = i;
  63.     }
  64.     if (s[i] == ')')
  65.     {
  66.       if (!c1 || i == p+1)
  67.     return false;      
  68.       c2++;
  69.     }
  70.     if (!c1 && s[i] == ',')
  71.       return false;
  72.     if (c1 && !p && s[i] == ',')
  73.       return false;
  74.   }
  75.   if (c1 != c2)
  76.     return false;
  77.   return true;
  78. }
  79. bool check_operators(std::string s)
  80. {
  81.   int len = s.length();
  82.   if (s[len-1] != ')' && precedence(s[len-1]))
  83.     return false;
  84.   if (precedence(s[0]) && s[0]!='!' && s[0]!='-' && s[0]!='+' && s[0]!='(' && s[0]!= ')')  
  85.       return false;  
  86.   int p;
  87.   for (int i = len-1;i >= 0;--i)
  88.   {  
  89.     if (s[i] == ')')
  90.     {
  91.       p = i;
  92.       break;
  93.     }
  94.   }
  95.   for (int i = 0;i<len;++i)
  96.   {  
  97.     if (s[i] == '(')
  98.     {
  99.       if (s[i+1] == ',')
  100.     return false;
  101.       while (++i != p)
  102.       {
  103.       if (s[i] != '(' && s[i] != ')')
  104.         if (precedence(s[i]) && s[i+1] != '(' && precedence(s[i+1]))
  105.           return false;
  106.       }
  107.       if (i != len-1 && s[i+1] == ',')
  108.     return false;
  109.     }
  110.     if (s[i] != '(' && s[i] != ')' && s[i+1] != '(' && s[i+1] != ')'&& precedence(s[i]) && precedence(s[i+1]))
  111.     return false;
  112.   }
  113.   return true;  
  114. }
  115. std::string func_type(std::string s)
  116. {
  117.   static int size=sizeof(functions::binary_func)/sizeof(functions::binary_func[0]);
  118.   for(int i=0;i<size;++i)
  119.     if(s==functions::binary_func[i])
  120.       return "binary";
  121.   return "unary";
  122. }
  123. bool is_func(std::string s)
  124. {  
  125.   static int size1=sizeof(functions::unary_func)/sizeof(functions::unary_func[0]);
  126.   for (int i = 0;i<size1;++i)
  127.     if (functions::unary_func[i] == s)
  128.       return true;  
  129.   static int size2=sizeof(functions::binary_func)/sizeof(functions::binary_func[0]);
  130.   for (int i = 0;i<size2;++i)
  131.     if (functions::binary_func[i] == s)
  132.       return true;  
  133.   return false;
  134. }
  135. bool is_dig(char op)
  136. {
  137.   if(op>='0' && op<='9')
  138.       return true;
  139.   return false;
  140. }
  141. bool is_alpha(char op)
  142. {
  143.   if(op>='a' && op<='z')
  144.     return true;
  145.   return false;
  146. }
  147. bool check_functions(std::string s, std::vector<std::pair<std::string, int> > &my_func)
  148. {
  149.   int len = s.length();  
  150.   if (len == 1)
  151.   {
  152.     if (is_alpha(s[0]))
  153.       return false;
  154.     return true;
  155.   }  
  156.   for (int i = 0;i<len;++i)
  157.   {    
  158.     if (is_alpha(s[i]))
  159.     {
  160.       std::string s1;
  161.       bool flag = false;
  162.       s1.push_back(s[i]);
  163.       while (++i<len)
  164.       {
  165.     if (s[i] == '(')
  166.     {
  167.       flag = true;   
  168.       break;
  169.     }
  170.     s1.push_back(s[i]);
  171.       }      
  172.       if (!flag)
  173.     return false;  
  174.       if (is_func(s1))
  175.     my_func.push_back(std::make_pair(s1,i));    
  176.       else
  177.     return false;
  178.       int c = 0, k;      
  179.       std::string type=func_type(s1);
  180.       for(k=i+1;k<len-1;++k)
  181.       {
  182.         if(type=="binary" && s[k]==')' && (k+1==len || precedence(s[k+1]>=1)))
  183.       break;
  184.     else if(type=="unary" &&  s[k]==')')
  185.       break;
  186.       }
  187.       int pos=k;      
  188.       k=i;
  189.       while (++k!= pos && k<len)
  190.       {
  191.     if (is_alpha(s[k]))  
  192.       while (s[++k] != ')' && k<len);
  193.     if (type=="unary" && s[k] == ',')
  194.       return false;
  195.     else if(type=="binary" && s[k] == ',' && ++c>1)  
  196.         return false;  
  197.       }
  198.       if (type=="binary" && !c)        
  199.     return false;    
  200.     }    
  201.   }
  202.   return true;
  203. }
  204. bool check_syntax(std::string s, std::vector<std::pair<std::string, int> > &my_func)
  205. {
  206.   return check_braces_comma(s) && check_operators(s) && check_functions(s,my_func);  
  207. }
  208. void pop_operators(std::string &pf, std::stack<char> &stk)
  209. {
  210.   while (!stk.empty())
  211.   {
  212.       char t = stk.top();
  213.       if (t != '(')        
  214.     pf.push_back(stk.top());      
  215.       stk.pop();
  216.   }
  217. }
  218. void modify_pf(std::string s,std::string &pf,std::stack<char> &stk, int &i)
  219. {
  220.   if (s[i] == ')' || s[i]==',')
  221.   {
  222.     pop_operators(pf, stk);
  223.     if(s[i]==',')
  224.       pf.push_back(',');    
  225.   }
  226.   else if (precedence(s[i]))
  227.   {
  228.     char op = s[i];
  229.     if (stk.empty())
  230.     stk.push(op);
  231.     else
  232.     {
  233.     char t = stk.top();
  234.     if (precedence(op) <= precedence(t))
  235.     {      
  236.         if (t != '(')        
  237.           pf.push_back(stk.top());     
  238.         stk.pop();
  239.         stk.push(op);
  240.     }
  241.     else
  242.       stk.push(op);
  243.     }
  244.   }  
  245.   else
  246.      pf.push_back(s[i]);  
  247. }
  248. std::string add_spaces(std::string s)
  249. {
  250.   std::string s1;
  251.   int len=s.length();
  252.   for(int i=0;i<len;++i)
  253.   {
  254.     if(s[i]==' ')
  255.       continue;
  256.     while(i<len && is_alpha(s[i]))
  257.     {
  258.       s1.push_back(s[i++]);
  259.       if(s[i]==' ')
  260.     s1.push_back(' ');
  261.     }
  262.     while(i<len && is_dig(s[i]))
  263.     {
  264.       s1.push_back(s[i++]);
  265.       if(s[i]==' ')
  266.     s1.push_back(' ');
  267.     }
  268.     if(s[i]!=' ' && precedence(s[i]))
  269.     {
  270.       s1.push_back(s[i]);
  271.       s1.push_back(' ');
  272.     }
  273.     if(s[i]=='.')
  274.       s1.push_back('.');
  275.   }
  276.   return s1;
  277. }
  278. std::string to_postfix(std::string s)
  279. {
  280.   std::stack<char> stk;
  281.   std::string pf;
  282.   int len = s.length();
  283.   for (int i = 0;i<len;++i)
  284.   {    
  285.     if (s[i] == '(')
  286.     {
  287.       stk.push(s[i]);
  288.       while (s[++i] != ')' && i<len)
  289.       {
  290.     if (s[i] == '(')
  291.       stk.push(s[i]);
  292.     modify_pf(s,pf,stk,i); 
  293.       }
  294.     }
  295.     modify_pf(s,pf,stk,i);
  296.   }
  297.   pop_operators(pf, stk);
  298.   return add_spaces(pf);  
  299. }
  300. std::string eval_func(std::string s,std::vector<std::pair<std::string, int> > &my_func) {}
  301. double operation(double a, double b, char op)
  302. {
  303.   switch (op)
  304.   {
  305.     case '+': return a+b;
  306.     case '-': return a-b;
  307.     case '*': return a*b;
  308.     case '/': return a/b;
  309.     case '%': return std::fmod(a, b);    
  310.   }
  311. }
  312. int to_num(std::string s, int &i, double &n)
  313. {
  314.   int c = 0;
  315.   while (is_dig(s[i]) && i<s.length())
  316.   {
  317.     c++;
  318.     n = n*10+(s[i++]-48);
  319.   }
  320.   return c;
  321. }
  322. double result(std::string s)
  323. {
  324.   int len = s.length();  
  325.   std::stack<double> stk;
  326.   for (int i = 0;i<len;++i)
  327.   {  
  328.     if (s[i] == ' ')
  329.       continue;
  330.     double num = 0, k = 0;
  331.     int c = to_num(s, i, num);    
  332.     if (s[i] == '.')    
  333.       c = -to_num(s, ++i, k);
  334.     num += k*std::pow(10, c);
  335.     if (c)
  336.       stk.push(num);    
  337.     if (s[i] != ' ' && precedence(s[i]))
  338.     {
  339.       double a = stk.top();
  340.       stk.pop();
  341.       double b=0;
  342.       if(stk.size()>=1)
  343.       {
  344.      b = stk.top();
  345.      stk.pop();
  346.       }      
  347.       stk.push(operation(b, a, s[i]));
  348.     }      
  349.   }
  350.   double r = stk.top();
  351.   stk.pop();
  352.   return r;
  353. }
  354. std::string remove_spaces(std::string s)
  355. {
  356.   int len = s.length();
  357.   std::string s1;
  358.   for (int i = 0;i<len;++i)
  359.   {
  360.     if (s[i] == ' ')
  361.       continue;
  362.     s1.push_back(s[i]);
  363.   }
  364.   return s1;
  365. }
  366. int main()
  367. {
  368.   std::string s;  
  369.   while (std::getline(std::cin, s))
  370.   {
  371.     try
  372.     {      
  373.       if(!s.length())
  374.     throw std::runtime_error("Invalid entry");
  375.       s = remove_spaces(s);
  376.       std::vector<std::pair<std::string, int> > my_func;
  377.       if(!check_syntax(s,my_func))
  378.     throw std::runtime_error("Syntax error");
  379.       std::string infix= modify_str(s);
  380.       std::cout <<"Infix: "<< infix << "\n";
  381.       std::string pf(infix);
  382.       /*if (!my_func.empty())
  383.     pf= eval_func(infix, my_func);*/      
  384.       pf = to_postfix(pf);      
  385.       std::cout << "Postfix: "<<pf <<  "\n";    
  386.       if(my_func.empty())
  387.       {
  388.     double val = result(pf);
  389.     std::cout << "Result= "<< val << "\n";      
  390.       }
  391.       else
  392.       {
  393.     std::cout<<"Function evaluation to be implemented later :P\n";
  394.       }
  395.     }
  396.     catch (const std::exception &e)
  397.     {
  398.       std::cerr<<e.what() << "\n";
  399.     }
  400.   }  
  401.   return 0;
  402. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement