Advertisement
Argent007

Expression Calculation 2024

Dec 21st, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.13 KB | None | 0 0
  1. // CalcExpression.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <stack>
  9. #include <map>
  10. #include <functional>
  11. #include <numeric>
  12.  
  13. using namespace std;
  14.  
  15. enum class term_t { var, constant, func, oper, op_br, cl_br};
  16.  
  17. struct term
  18. {
  19.     std::string name;
  20.     term_t type;
  21. };
  22.  
  23. std::vector<term> parse_string_to_terms(const std::string& expr)
  24. {
  25.     std::vector<term> res;
  26.     auto it = expr.begin();
  27.     while (it != expr.end())
  28.     {
  29.         if (std::isspace(*it)) { ++it;  continue;  }
  30.         auto termend = std::find_if(it, expr.end(), [](auto c) {return !std::isalnum(c) && c != '.'; });
  31.         if (it == termend) ++termend;
  32.         res.push_back({ std::string(it, termend), term_t::oper });
  33.         it = termend;
  34.     }
  35.     for (size_t i = 0; i < res.size(); i++)
  36.     {
  37.         char c = res[i].name[0];
  38.         if (std::isdigit(c)) res[i].type = term_t::constant;
  39.         else if (std::isalpha(c))
  40.             if (i < res.size() - 1 && res[i + 1].name == "(")
  41.                 res[i].type = term_t::func;
  42.             else
  43.                 res[i].type = term_t::var;
  44.         else if (c == '(') res[i].type = term_t::op_br;
  45.         else if (c == ')') res[i].type = term_t::cl_br;
  46.     }
  47.     return res;
  48. }
  49.  
  50. std::map<string, int> priority{ {"^",100}, {"*",70}, {"/",70}, {"%",70},
  51.     {"+",40}, {"-",40}, {">",20}, {"<",20} };
  52.  
  53. vector<term> expression_terms_to_postfix(const vector<term>& terms)
  54. {
  55.     vector<term> pstfx;
  56.     stack<term> s;
  57.     for (const auto& t : terms)
  58.         switch (t.type)
  59.         {
  60.         case term_t::constant:
  61.         case term_t::var: pstfx.push_back(t); break;
  62.         case term_t::func:
  63.         case term_t::op_br:s.push(t); break;
  64.         case term_t::cl_br:
  65.             while (s.top().type != term_t::op_br)
  66.             {
  67.                 pstfx.push_back(s.top());
  68.                 s.pop();
  69.             }
  70.             s.pop();
  71.             break;
  72.         case term_t::oper:
  73.             while (s.size() && (s.top().type == term_t::func or
  74.                 s.top().type == term_t::oper && priority[s.top().name] >= priority[t.name]))
  75.             {
  76.                 pstfx.push_back(s.top());
  77.                 s.pop();
  78.             }
  79.             s.push(t);
  80.         }
  81.     while (s.size())
  82.     {
  83.         pstfx.push_back(s.top());
  84.         s.pop();
  85.     }
  86.     return pstfx;
  87. }
  88.  
  89. using operations = std::map<std::string, std::function<double(std::stack<double>&)>>;
  90.  
  91. double pop(std::stack<double>& s)
  92. {
  93.     auto res = s.top();
  94.     s.pop();
  95.     return res;
  96. }
  97.  
  98. operations ops{
  99.     {"+",[](std::stack<double>& s) {return pop(s) + pop(s); }},
  100.     {"-",[](std::stack<double>& s) {return -pop(s) + pop(s); }},
  101.     {"*",[](std::stack<double>& s) {return pop(s) * pop(s); }},
  102.     {"/",[](std::stack<double>& s) {return 1 / pop(s) * pop(s); }},
  103.     {"^",[](std::stack<double>& s) { double p = pop(s); return pow(pop(s),p); }},
  104.     {"exp",[](std::stack<double>& s) {return exp(pop(s)); }},
  105.     {"cos",[](std::stack<double>& s) {return cos(pop(s)); }},
  106.     {">",[](std::stack<double>& s) {return pop(s) < pop(s); }},
  107.     {"<",[](std::stack<double>& s) {return pop(s) > pop(s); }},
  108. };
  109.  
  110. double postfix_calc(const vector<term>& pstfx, operations& ops, map<string, double>& vars)
  111. {
  112.     stack<double> s;
  113.     for (auto& t : pstfx)
  114.         switch (t.type)
  115.         {
  116.         case term_t::var: s.push(vars[t.name]); break;
  117.         case term_t::constant: s.push(stod(t.name)); break;
  118.         case term_t::func:
  119.         case term_t::oper: s.push(ops[t.name](s)); break;
  120.         }
  121.     return s.top();
  122. }
  123.  
  124. int main()
  125. {
  126.     std::string expr = "3.15*abc+exp(x^2-cos(x-y-z/x*y))";
  127.     auto terms = parse_string_to_terms(expr);
  128.     auto pstx = expression_terms_to_postfix(terms);
  129.     for (auto t : pstx)
  130.         std::cout << t.name << " " << (int)t.type << std::endl;
  131.     std::map<string, double> vars{ {"abc", 3.0}, {"x", 2.5}, {"y", -1.1}, {"z", 0.1}};
  132.     std::cout << postfix_calc(pstx,ops,vars) << std::endl;
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement