Advertisement
Sanlover

Untitled

Oct 20th, 2020
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. #include <iostream>
  2. #include <conio.h>
  3. #include <string>
  4. using namespace std;
  5. #define COUNT 15
  6.  
  7. struct TNode
  8. {
  9. char data;
  10. TNode* left;
  11. TNode* right;
  12. };
  13.  
  14. typedef TNode* PNode;
  15.  
  16. PNode root = NULL;
  17.  
  18. string erase(string msg)
  19. {
  20. int n = msg.length();
  21. for (int i = 0; i < n; i++)
  22. {
  23. if (msg[i] == ' ')
  24. {
  25. msg.erase(i, 1);
  26. n--;
  27. }
  28. }
  29. return msg;
  30. }
  31.  
  32. // correct_paranthesis - проверка на баланс строка в левой и правой частях
  33. bool correct_paranthesis(string s)
  34. {
  35. int am = 0;
  36. for (int i = 0; i < s.length(); i++)
  37. {
  38. if (s[i] == '(')
  39. am++;
  40. if (s[i] == '(')
  41. am--;
  42. if (am < 0)
  43. return false;
  44. }
  45. return (am == 0);
  46. }
  47.  
  48.  
  49. // parse - сама реализация парсинга, посредством рекурсии
  50. PNode parse(string str)
  51. {
  52. // Наши операторы
  53. char operators[4] = { '+' , '-' , '*' , '/' };
  54.  
  55. // Длина строки
  56. size_t strLenght = str.length();
  57.  
  58. // Уровень
  59. int* symbolDepth = new int[strLenght];
  60.  
  61.  
  62. // До следующего For'a просто подсчитываем уровень всей строки
  63. if (str[0] == '(')
  64. symbolDepth[0] = 1;
  65. else
  66. symbolDepth[0] = 0;
  67. for (size_t i = 1; i < strLenght; i++)
  68. {
  69. symbolDepth[i] = symbolDepth[i - 1];
  70. if (str[i] == '(')
  71. {
  72. symbolDepth[i]++;
  73. }
  74. else if (str[i] == ')')
  75. {
  76. symbolDepth[i]--;
  77. }
  78. }
  79.  
  80. // Взяв j знак(умнож/дел и т.п.) ищем позицию этого знака в строке, если он конечно есть
  81. for (int j = 0; j < 4; j++)
  82. {
  83. int position = -1;
  84. for (int i = 0; i < strLenght; i++)
  85. {
  86. if (str[i] == operators[j] && symbolDepth[i] == 0 && position == -1)
  87. {
  88. position = i;
  89. break;
  90. }
  91. }
  92.  
  93. // Если нашёлся знак, то
  94. if (position != -1)
  95. {
  96. string left = str.substr(0, position); // Делим на левую часть
  97. string right = str.substr(position + 1, strLenght - position - 1); // И правую ( от знака ) 2+3 = 2 и 3
  98.  
  99. if (correct_paranthesis(left) && correct_paranthesis(right)) // Если все скобки в правой и левой частях закрыты, то продолжаем
  100. {
  101. PNode result = new TNode; // Выделяем память под результат
  102.  
  103. result->data = operators[j]; // Запоминаем знак
  104. result->left = parse(left); // И говорим, что то, что отправится в парсинг будет нашей левой
  105. result->right = parse(right); // и правой частями соответственно
  106. return result; // После выполнения рекурсий для left и right просто возвращаем наш созданный узел со знаком и левой и правыми частями, которые мы уже пропарсили
  107. }
  108. }
  109. }
  110.  
  111. // Если знака не нашлось, то проверяем, закрыта ли у нас целиком строчка с двух сторон скобками, если да, то очищаем и отправляем в парс её
  112. if (str[0] == '(' && str[strLenght - 1] == ')')
  113. {
  114. string clean = str.substr(1, strLenght - 2);
  115. return parse(clean);
  116. }
  117.  
  118. // Если нет (Не нашлось ни знаков, ни скообок, то это число)
  119.  
  120. PNode result = new TNode;
  121. result->data = str[0]; // Поскольку числа <10 , то лишь один символ останется
  122. result->left = NULL; // Это край, поэтому зануляем концы
  123. result->right = NULL;
  124. return result;
  125. }
  126.  
  127. // print - вывод дерева
  128. void print(PNode root, int space)
  129. {
  130. if (root == NULL)
  131. return;
  132.  
  133. space += COUNT;
  134.  
  135. print(root->right, space);
  136.  
  137. cout << endl;
  138. for (int i = COUNT; i < space; i++)
  139. cout << " ";
  140. cout << root->data << "\n";
  141.  
  142. print(root->left, space);
  143. }
  144.  
  145. int main()
  146. {
  147. setlocale(LC_CTYPE, "Russian");
  148.  
  149. string s;
  150. cout << "Введите выражение: ";
  151.  
  152. getline(cin, s);
  153.  
  154. string p = erase(s);
  155.  
  156. root = parse(p);
  157.  
  158. print(root, 0);
  159.  
  160. system("pause");
  161. return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement