Advertisement
Guest User

Shunting Yard Basic

a guest
Nov 24th, 2021
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.45 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. constexpr unsigned int str2int(const char* str, int h = 0)
  5. {
  6.     return !str[h] ? 5381 : (str2int(str, h+1) * 33) ^ str[h];
  7. }
  8.  
  9. bool isNumber(const string& s)
  10. {
  11.    if(s.empty() || ::isspace(s[0]) || isalpha(s[0])) {
  12.        return false;
  13.    }
  14.    char *p;
  15.    strtod(s.c_str(), &p);
  16.  
  17.    return (*p == 0);
  18. }
  19.  
  20. double operation(string s, double v1, double v2)
  21. {
  22.     switch(str2int(s.c_str())) {
  23.         case str2int("+"):
  24.             return v1 + v2; break;
  25.         case str2int("-"):
  26.             return v1 - v2; break;
  27.         case str2int("*"):
  28.             return v1 * v2; break;
  29.         case str2int("/"):
  30.             return v1 / v2; break;
  31.         case str2int("^"):
  32.             return pow(v1, v2); break;
  33.         /*case '!':
  34.             return tgamma(v1 + 1); break;*/
  35.         default:
  36.             cout << "???\n";
  37.     }
  38.  
  39.     return 1;
  40. }
  41. bool isoperator(string s)
  42. {
  43.     vector<string> v {"+", "-", "*", "/", "^"};
  44.  
  45.     return find(v.begin(), v.end(), s) != v.end();
  46. }
  47.  
  48. bool isfunction(string s)
  49. {
  50.     vector<string> v {"sin", "cos", "tan", "ln", "log", "sqrt", "!", "cbrt", "abs", "asin", "acos", "atan"};
  51.  
  52.     return find(v.begin(), v.end(), s) != v.end();
  53. }
  54.  
  55. double evaluate(queue<string> q)
  56. {
  57.     stack<double> newstack;
  58.     const int qsize = q.size();
  59.     for (int i = 0; i < qsize; ++i) {
  60.         if (isNumber(q.front())) {
  61.             newstack.push(stod(q.front()));
  62.             q.pop();
  63.         }
  64.         //continue later
  65.         else if (isoperator(q.front())) {
  66.             double val1 = newstack.top();
  67.             newstack.pop();
  68.             double val2 = newstack.top();
  69.             newstack.pop();
  70.             newstack.push(operation(q.front(), val2, val1));
  71.             q.pop();
  72.         }
  73.     }
  74.  
  75.     return newstack.top();
  76. }
  77.  
  78. queue<string> parse(string input)
  79. {
  80.     map<string, int> m {{"+", 0}, {"-", 0}, {"*", 1}, {"/", 1}, {"^", 2}, {"(", 4}, {")", 4}}; //operator precedence
  81.     map<string, char> assoc {{"+", 'l'},  {"-", 'l'}, {"*", 'l'}, {"/", 'l'}, {"^", 'r'}, {"(", 'l'}, {")", 'l'}}; //operator associativity
  82.  
  83.  
  84.     stack<string> operate;
  85.     queue<string> que;
  86.  
  87.     for (int i = 0; i < input.length(); ++i) {
  88.         string s = input.substr(i, 1);
  89.         if (isNumber(s)) {
  90.             que.push(s);
  91.         }
  92.         //edit mechanism of this part later
  93.         else if (isfunction(s)) {
  94.             operate.push(s);
  95.         }
  96.         else if (isoperator(s)) {
  97.             while (operate.size() != 0 && operate.top() != "(" && (m[operate.top()] > m[s] || (m[s] == m[operate.top()] && assoc[s] == 'l'))) {
  98.                 que.push(operate.top());
  99.                 operate.pop();
  100.             }
  101.             operate.push(s);
  102.         }
  103.         else if (s == "(") {
  104.             operate.push(s);
  105.         }
  106.         else if (s == ")") {
  107.             while (operate.top() != "(") {
  108.                 que.push(operate.top());
  109.                 operate.pop();
  110.             }
  111.             operate.pop();
  112.             //add if statement for function
  113.         }
  114.     }
  115.    
  116.     const int osize = operate.size();
  117.     for (int i = 0; i < osize; ++i) {
  118.         que.push(operate.top());
  119.         operate.pop();
  120.     }
  121.  
  122.     return que;
  123. }
  124.  
  125. int main()
  126. {
  127.     cout << "Enter: \n";
  128.     string input;
  129.     getline(cin, input);
  130.     input.erase(remove_if(input.begin(), input.end(), ::isspace), input.end());
  131.  
  132.     cout << "answer: \n";
  133.     cout << evaluate(parse(input));
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement