Advertisement
Guest User

Untitled

a guest
Nov 12th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.78 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <stack>
  4. #include <string>
  5. #include <algorithm>
  6. #include <Windows.h>
  7.  
  8. using namespace std;
  9.  
  10. enum class ttype
  11. {
  12. var,
  13. cnst,
  14. opbr,
  15. clbr,
  16. op,
  17. fun
  18. };
  19.  
  20. const string delimiters = " +-*/()^";
  21.  
  22. USHORT prior(string term) //Приоритет операций
  23. {
  24. return term == "+" || term == "-" ? 0
  25. : term == "*" || term == "/" ? 1
  26. : term == "^" ? 2 :
  27. term == "(" ? 3 : USHRT_MAX;
  28. }
  29.  
  30. struct term
  31. {
  32. string name;
  33. ttype type;
  34. };
  35.  
  36. bool isDelimiter(char c)
  37. {
  38. return find(begin(delimiters), end(delimiters), c) != end(delimiters);
  39. }
  40.  
  41. vector<term> convertToTerms(string expr)
  42. {
  43. expr += ' ';
  44. vector<term> terms;
  45. size_t i = 0;
  46. while (i < expr.length())
  47. {
  48. string t = "";
  49. if (expr[i] == ' ')
  50. {
  51. i++;
  52. continue;
  53. }
  54. do
  55. {
  56. t += expr[i++];
  57. } while (!isDelimiter(expr[i - 1]) && !isDelimiter(expr[i]));
  58. terms.push_back({ t,ttype::op });
  59. }
  60. for (size_t i = 0; i < terms.size(); i++)
  61. {
  62. char c = terms[i].name[0];
  63. if (c == '(')
  64. {
  65. terms[i].type = ttype::opbr;
  66. }
  67.  
  68. else if (c == ')')
  69. {
  70. terms[i].type = ttype::clbr;
  71. }
  72.  
  73. else if (isalpha(c))
  74. {
  75. if (i < terms.size() - 1 && terms[i + 1].name == "(")
  76. {
  77. terms[i].type = ttype::fun;
  78. }
  79. else
  80. {
  81. terms[i].type = ttype::var;
  82. }
  83. }
  84. else if (isdigit(c))
  85. {
  86. terms[i].type = ttype::cnst;
  87. }
  88. }
  89. return terms;
  90. }
  91.  
  92. vector<term> convertToPostfix(const vector<term>& terms)
  93. {
  94. stack<term> s; //Префиксная запись реализуется через стек
  95. vector<term> res; //Результирующая строка
  96.  
  97. for (const auto& i : terms)
  98. {
  99. switch (i.type)
  100. {
  101. case ttype::cnst: //Если встречается константа или переменная или функция (sin,exp) то кладем сразу в результирующую строку
  102. case ttype::var:
  103. case ttype::fun:
  104. res.push_back(i);
  105. break;
  106.  
  107. case ttype::opbr: //Открывающую скобку с стек
  108. s.push(i);
  109. break;
  110.  
  111. case ttype::clbr: //Если встретилась закрывающая скобка, то вставляются все элементы из стека пока не найдется открывающая скобка
  112. while (s.top().type != ttype::opbr)
  113. {
  114. res.push_back(s.top());
  115. s.pop();
  116. }
  117. s.pop();
  118. break;
  119.  
  120. /*
  121. Если операция o1
  122. 1) пока на вершине стека префиксная функция…
  123. … ИЛИ операция на вершине стека приоритетнее o1
  124. … ИЛИ операция на вершине стека левоассоциативная с приоритетом как у o1
  125. … выталкиваем верхний элемент стека в выходную строку;
  126. 2) помещаем операцию o1 в стек.
  127. */
  128. case ttype::op:
  129. if (s.size())
  130. {
  131. while (s.top().type == ttype::op && prior(s.top().name) > prior(i.name) ||
  132. (prior(s.top().name) == prior(i.name) && prior(s.top().name) != 2))
  133. {
  134. res.push_back(s.top());
  135. s.pop();
  136. }
  137. }
  138. s.push(i);
  139. break;
  140. }
  141. }
  142.  
  143. while (!s.empty()) //Весь оставшийся стек помещаем в конец результирующей строки
  144. {
  145. res.push_back(s.top());
  146. s.pop();
  147. }
  148.  
  149. return res;
  150. }
  151.  
  152. int main()
  153. {
  154. const string expr = "abc+3.15*exp(2*cos(a-b/c)^(ab-c)+1.2)";
  155. auto terms = convertToTerms(expr);
  156.  
  157. /*for (const auto& t : terms)
  158. {
  159. cout << t.name << " " << static_cast<int>(t.type) << endl;
  160. }*/
  161.  
  162. terms = convertToPostfix(terms);
  163.  
  164. for (size_t i = 0; i < terms.size(); i++)
  165. {
  166. cout << terms[i].name << " ";
  167. }
  168.  
  169. return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement