fork(1) download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <stdbool.h>
  5.  
  6. // Максимальное количество цифр в числе.
  7. #define N 20
  8.  
  9. bool err; // Проверка ошибок.
  10.  
  11. double calc(void);
  12. int pri(char);
  13.  
  14. int main(void)
  15. {
  16. double num;
  17.  
  18. puts("Math 0.0.3 by Mr. Anonson, 2019");
  19.  
  20. while (true)
  21. {
  22. printf("%s", "> ");
  23.  
  24. num = calc();
  25. if (!err)
  26. printf("%.16g\n", num);
  27. }
  28.  
  29. return 0;
  30. }
  31.  
  32. // Расчет введенного выражения.
  33. double calc(void)
  34. {
  35. bool br = false; // Флаг открытия скобок.
  36. int i = 0; // Положение в строке.
  37. int j = 0; // Положение в стеках.
  38. int k = 0; // Положение рабочей области в стеках.
  39. int f = 0; // Флаг конца выражения и понижения приоритета.
  40. char ch; // Считываемый с ввода символ.
  41. char str[N]; // Строка под число.
  42. char op[3]; // Стек операторов.
  43. double num[3]; // Стек чисел.
  44.  
  45. err = true;
  46. do
  47. {
  48. ch = getchar();
  49.  
  50. // Парсим ввод на числа и операторы.
  51. switch (ch)
  52. {
  53. case '0':
  54. case '1':
  55. case '2':
  56. case '3':
  57. case '4':
  58. case '5':
  59. case '6':
  60. case '7':
  61. case '8':
  62. case '9':
  63. case '.':
  64. if (err)
  65. err = false;
  66. if (i < N-1)
  67. {
  68. str[i] = ch; // Кладем цифоры в строку.
  69. i++;
  70. }
  71. break;
  72.  
  73. case '*':
  74. case '/':
  75. if (j > 0 && pri(ch) > pri(op[k]))
  76. k++;
  77. op[j] = ch; // Загоняем символы операторов в стек.
  78. if (!br)
  79. {
  80. str[i] = '\0';
  81. num[j] = atof(str); // Переводим строку в число и загоняем в стек.
  82. }
  83. else
  84. br = false;
  85. i = 0;
  86. j++;
  87. break;
  88.  
  89. case '+':
  90. case '-':
  91. if (k > 0)
  92. f++;
  93. op[j] = ch;
  94. if (!br)
  95. {
  96. str[i] = '\0';
  97. num[j] = atof(str);
  98. }
  99. else
  100. br = false;
  101. i = 0;
  102. j++;
  103. break;
  104.  
  105. case '(':
  106. br = true;
  107. num[j] = calc(); // Скобочная рекурсия.
  108. break;
  109.  
  110. case ')':
  111. case '\n':
  112. if (k > 0)
  113. f = k;
  114. if (!br)
  115. {
  116. str[i] = '\0';
  117. num[j] = atof(str);
  118. }
  119. i = 0;
  120. j++;
  121. break;
  122. }
  123.  
  124. while (j > k+1)
  125. {
  126. /* // Для отладки.
  127. printf("%c %g\n", op[0], num[0]);
  128. printf("%c %g\n", op[1], num[1]);
  129. printf("%c %g\n\n", op[2], num[2]); */
  130.  
  131. // Считаем выражения.
  132. switch (op[k])
  133. {
  134. case '+':
  135. num[k] += num[k+1];
  136. break;
  137. case '-':
  138. num[k] -= num[k+1];
  139. break;
  140. case '*':
  141. num[k] *= num[k+1];
  142. break;
  143. case '/':
  144. num[k] /= num[k+1];
  145. break;
  146. }
  147.  
  148. op[k] = op[k+1]; // Сдвиг стека операторов.
  149. j--;
  150. if (f > 0)
  151. {
  152. k--;
  153. f--;
  154. }
  155. }
  156. }
  157. while (ch != '\n' && ch != ')');
  158.  
  159. return num[0];
  160. }
  161.  
  162.  
  163. // Приоритет оператора.
  164. int pri(char ch)
  165. {
  166. int pr;
  167.  
  168. switch (ch)
  169. {
  170. case '+':
  171. case '-':
  172. pr = 1;
  173. break;
  174. case '*':
  175. case '/':
  176. pr = 2;
  177. break;
  178. }
  179.  
  180. return pr;
  181. }
Time limit exceeded #stdin #stdout 5s 9424KB
stdin
Standard input is empty
stdout
Standard output is empty