Advertisement
Guest User

Untitled

a guest
Mar 28th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.48 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <conio.h>
  4. #include <map>
  5. #include <string>
  6. #include <cstdlib>
  7. #include <sstream>
  8. #include <math.h>
  9. using namespace std;
  10.  
  11. typedef float Data;
  12. /************************
  13. * структура операции над числом
  14. * c - символ операции
  15. * prior - приоритет операции
  16. *
  17. *************************/
  18. struct Operation
  19. {
  20.     char c;
  21.     int prior;
  22. };
  23.  
  24. /************************
  25. * структура стека для чисел:
  26. * top - индекс первого пустого элемента
  27. * capacity - емкость стека
  28. * a - указатель на массив данных
  29. *************************/
  30. struct sNum
  31. {
  32.     int top;
  33.     int capacity;
  34.     Data * a;
  35. };
  36.  
  37. /************************
  38. * структура стека для операций:
  39. * top - индекс первого пустого элемента
  40. * capacity - емкость стека
  41. * a - указатель на массив данных
  42. *************************/
  43. struct sOp
  44. {
  45.     int top;
  46.     int capacity;
  47.     Operation * a;
  48. };
  49.  
  50. //sNum methods
  51. sNum * createsNum(int capacity);
  52. Data popNum(sNum * s);
  53. void printsNum(sNum * s);
  54. void pushNum(sNum * s, Data x);
  55. bool isEmpty(sNum * s);
  56. bool isFull(sNum * s);
  57. void destroysNum(sNum * s);
  58.  
  59. //sOp methods
  60. sOp * createsOp(int capacity);
  61. Operation popOp(sOp * s);
  62. void printsOp(sOp * s);
  63. void pushOp(sOp * s, Operation x);
  64. bool isEmpty(sOp * s);
  65. bool isFull(sOp * s);
  66. void destroysNum(sOp * s);
  67.  
  68. #pragma region StackNumbers
  69. /*****************************************
  70. * void printsNum():
  71. * параметры - sNum * s
  72. * назначение - печать содержмиого стека.
  73. *****************************************/
  74. void printsNum(sNum * s)
  75. {
  76.     for (int i = 0; i < s->top; i++)
  77.     {
  78.         printf("%d ", s->a[i]);
  79.     }
  80.  
  81.     cout << "\n";
  82. }
  83.  
  84. /********************************************************************
  85. * sNum * createsNum():
  86. * параметры - int capacity
  87. * назначение - cоздает стек, выделяя под него память динамически
  88. *********************************************************************/
  89. sNum * createsNum(int capacity)
  90. {
  91.     //sNum * sNum = (sNum*)malloc(sizeof(sNum) + (capacity - 1) * (sizeof(Data)));
  92.     sNum * stack = (sNum*)malloc(sizeof(sNum));
  93.     stack->top = 0;
  94.     stack->capacity = capacity;
  95.     stack->a = (Data*)malloc(capacity * sizeof(Data));
  96.     return stack;
  97. }
  98.  
  99. /**************************************************************
  100. * void pushNum():
  101. * параметры - sNum * s, Data x
  102. * назначение - добавление элемента в стек на верхнюю позицию.
  103. ***************************************************************/
  104. void pushNum(sNum * s, Data x)
  105. {
  106.     if (s->top >= s->capacity)
  107.     {
  108.         s->capacity += 10;
  109.         //s = (sNum*)realloc(sizeof(sNum) + s->capacity * (sizeof(Data)));
  110.         s->a = (Data*)realloc(s->a, (s->capacity) * sizeof(Data));
  111.     }
  112.  
  113.     s->a[s->top] = x;
  114.     s->top += 1;
  115. }
  116.  
  117. /***********************************************
  118. * Data popNum():
  119. * параметры - sNum * s
  120. * назначение - берет последний сверху элемент
  121. ***********************************************/
  122. Data popNum(sNum * s)
  123. {
  124.     Data x = s->a[s->top - 1];
  125.     //s->a[s->top - 1] = 0;
  126.     s->top -= 1;
  127.     return x;
  128. }
  129.  
  130. /******************************************
  131. * bool isEmpty():
  132. * параметры - sNum * s
  133. * назначение - проверка стека на пустоту
  134. *******************************************/
  135. bool isEmpty(sNum * s)
  136. {
  137.     return s->top == 0;
  138. }
  139.  
  140. /******************************************
  141. * bool isFull():
  142. * параметры - sNum * s
  143. * назначение - проверка стека на полноту
  144. *******************************************/
  145. bool isFull(sNum * s)
  146. {
  147.     return s->top == s->capacity;
  148. }
  149.  
  150. /******************************************
  151. * void destroysNum():
  152. * параметры - sNum * s
  153. * назначение - удаление стека из памяти
  154. *******************************************/
  155. void destroysNum(sNum * s)
  156. {
  157.     free(s->a);
  158.     s->a = NULL;
  159.     free(s);
  160. }
  161. #pragma endregion End
  162.  
  163. #pragma region StackOperations
  164. void printsOp(sOp * s)
  165. {
  166.     for (int i = 0; i < s->top; i++)
  167.     {
  168.         printf("%c ", s->a[i].c);
  169.         printf("%d ", s->a[i].prior);
  170.     }
  171.  
  172.     cout << "\n";
  173. }
  174.  
  175. sOp * createsOp(int capacity)
  176. {
  177.     //sNum * sNum = (sNum*)malloc(sizeof(sNum) + (capacity - 1) * (sizeof(Data)));
  178.     sOp * stack = (sOp*)malloc(sizeof(sOp));
  179.     stack->top = 0;
  180.     stack->capacity = capacity;
  181.     stack->a = (Operation*)malloc(capacity * sizeof(Operation));
  182.     return stack;
  183. }
  184.  
  185. void pushOp(sOp * s, Operation x)
  186. {
  187.     if (s->top >= s->capacity)
  188.     {
  189.         s->capacity += 10;
  190.         //s = (sNum*)realloc(sizeof(sNum) + s->capacity * (sizeof(Data)));
  191.         s->a = (Operation*)realloc(s->a, (s->capacity) * sizeof(Operation));
  192.     }
  193.  
  194.     s->a[s->top].c = x.c;
  195.     s->a[s->top].prior = x.prior;
  196.     s->top += 1;
  197. }
  198.  
  199. Operation popOp(sOp * s)
  200. {
  201.     Operation x = s->a[s->top - 1];
  202.     //s->a[s->top - 1] = 0;
  203.     s->top -= 1;
  204.     return x;
  205. }
  206.  
  207. bool isEmpty(sOp * s)
  208. {
  209.     return s->top == 0;
  210. }
  211.  
  212. bool isFull(sOp * s)
  213. {
  214.     return s->top == s->capacity;
  215. }
  216.  
  217. void destroysOp(sOp * s)
  218. {
  219.     free(s->a);
  220.     s->a = NULL;
  221.     free(s);
  222. }
  223. #pragma endregion End
  224.  
  225. #pragma region Others
  226. /********************************************************
  227. * bool isDigit():
  228. * параметры - char * x
  229. * назначение - проверка символа, является ли он числом
  230. ********************************************************/
  231. bool isDigit(char * x)
  232. {
  233.  
  234.     if (*x <= '9' && *x >= '0')
  235.     {
  236.         return true;
  237.     }
  238.     else
  239.         return false;
  240. }
  241.  
  242. /*****************************************
  243. * float strToFloat():
  244. * параметры - string s
  245. * назначение - перевод строки во float.
  246. ******************************************/
  247. float strToFloat(string s)
  248. {
  249.     string p1 = "", p2 = "";
  250.     bool inp = true, start = false, go = false;
  251.     int countD = 0;
  252.     int pn1 = 0, pn2 = 0;
  253.     float num;
  254.     if (s.find('.'))
  255.     {
  256.         for (int i = 0; i < s.length(); i++)
  257.         {
  258.             if (s[i] == '.')
  259.             {
  260.                 inp = false;
  261.             }
  262.             if (s[i] != '.' && inp)
  263.             {
  264.                 p1 += s[i];
  265.             }
  266.             else if (!inp && s[i] != '.')
  267.             {
  268.                 countD++;
  269.                 if (s[i] != '0' && !start) start = true;
  270.                 if (start)
  271.                 {
  272.                     p2 += s[i];
  273.                 }
  274.             }
  275.         }
  276.  
  277.         istringstream ist1(p1);
  278.         ist1 >> pn1;
  279.  
  280.         istringstream ist2(p2);
  281.         ist2 >> pn2;
  282.  
  283.         num = (float)pn1 + (((float)pn2) / pow(10, countD));
  284.  
  285.     }
  286.     else
  287.     {
  288.         istringstream ist1(p1);
  289.         ist1 >> pn1;
  290.         num = float(pn1);
  291.     }
  292.  
  293.     return num;
  294. }
  295.  
  296. /***************************************************************
  297. * void calculate():
  298. * параметры - sOp * ops, sNum * nums
  299. * назначение - вытаскивает из стека два числа
  300. * и операцию из другого и применяет ее к этим двум элементам.
  301. * Потом результат кладет в стек с числами
  302. ****************************************************************/
  303. void calculate(sOp * ops, sNum * nums)  // вытащить из стека два операнда и одну операцию из другого
  304. {
  305.     float a, b, res = 0;
  306.     Operation op = popOp(ops);
  307.     char sign = op.c;
  308.     if (sign != '~')
  309.     {
  310.         a = popNum(nums);
  311.         b = popNum(nums);
  312.  
  313.         switch (sign)
  314.         {
  315.         case '+':
  316.             res = b + a;
  317.             break;
  318.         case '-':
  319.             res = b - a;
  320.             break;
  321.         case '*':
  322.             res = b * a;
  323.             break;
  324.         case '/':
  325.             res = b / a;
  326.             break;
  327.         case '^':
  328.             res = pow(b, a);
  329.             break;
  330.         }
  331.     }
  332.     else
  333.     {
  334.         a = popNum(nums);
  335.         res = 0 - a;
  336.     }
  337.  
  338.     op.c = NULL;
  339.     op.prior = NULL;
  340.     pushNum(nums, res);
  341. }
  342.  
  343. /*************************************************************
  344. * bool checkBrackets():
  345. * параметры - string s
  346. * назначение - проверяет введенное математическое выражение
  347. * на правильную расстановку скобок.
  348. ***************************************************************/
  349. bool checkBrackets(string s)
  350. {
  351.     int count = 0;
  352.     for (int i = 0; i < s.length(); i++)
  353.     {
  354.         if (s[i] == '(')
  355.             count++;
  356.         else if (s[i] == ')')
  357.             count--;
  358.     }
  359.  
  360.     if (count == 0)
  361.         return true;
  362.     else
  363.         return false;
  364. }
  365.  
  366. /*************************************************************
  367. * void deleteBracket():
  368. * параметры - sOp * s
  369. * назначение - При встрече открывающей и закрывающей скобок
  370. * нейтрализует их.
  371. ***************************************************************/
  372. void deleteBracket(sOp * s)
  373. {
  374.     Operation op = popOp(s);
  375.     op.c = NULL;
  376.     op.prior = NULL;
  377. }
  378. #pragma endregion End
  379. void main()
  380. {
  381.     map<char, int> dictOpsS = { { '@', 0 },
  382.                                 { '(', 1 },
  383.                                 { '*', 3 },
  384.                                 { '/', 3 },
  385.                                 { '%', 3 },
  386.                                 { '+', 2 },
  387.                                 { '-', 2 },
  388.                                 { '=', -1 },
  389.                                 { ')', 1 },
  390.                                 { '^', 4 },
  391.                                 { '~', 4 } };
  392.  
  393.     map<char, int> dictOpsComp = { { '@', 0 },
  394.                                    { '(', 100 },
  395.                                    { '*', 3 },
  396.                                    { '/', 3 },
  397.                                    { '%', 3 },
  398.                                    { '+', 2 },
  399.                                    { '-', 2 },
  400.                                    { '=', -1 },
  401.                                    { ')', 1 },
  402.                                    { '^', 4 },
  403.                                    { '~', 4 } };
  404.  
  405.     sOp * ops = createsOp(10);
  406.     sNum * nums = createsNum(10);
  407.  
  408.     Operation temp;
  409.     temp.prior = 0;
  410.     temp.c = '@';
  411.     pushOp(ops, temp);
  412.  
  413.     cout << "Enter the expression:\n";
  414.     string exp;
  415.     getline(cin, exp);
  416.  
  417.     string t = "";
  418.     if (checkBrackets(exp) && exp != "")         //проверка на пустоту выражения и правильность постановки скобок.
  419.     {
  420.         for (int i = 0; i < exp.length(); i++)
  421.         {
  422.             if (exp[i] == ' ') continue;
  423.             if (isDigit(&exp[i]) || exp[i] == '.')
  424.             {
  425.                 t += exp[i];                        //получение числа
  426.             }
  427.             else
  428.             {
  429.                 if (t != "") pushNum(nums, strToFloat(t));   //добавление в стек элемента и перевод его во float
  430.                 t = "";                                     //делаю пустым буфер для числа
  431.                 if (dictOpsComp[exp[i]] > ops->a[ops->top - 1].prior && dictOpsComp.count(exp[i]) != 0)        //если приоритет операции в списке "сравнения" больше, чем приоритет операции внутри стека, и эта операция есть в списке, в верх стека
  432.                 {
  433.                     temp.prior = dictOpsS[exp[i]];
  434.                     temp.c = exp[i];
  435.                     pushOp(ops, temp);
  436.                 }
  437.                 else if (dictOpsComp[exp[i]] <= ops->a[ops->top - 1].prior && dictOpsComp.count(exp[i]) != 0)    //если приор. операции меньше или равен опер., находящейся в стеке, то пока приоритет текущей операции <= оп. в стеке,
  438.                     //пока в стеке операндов есть 2 элемента, то вытаскивать из стека операндов 2 элемента, из стека операция одну операцию, применить ее по отношению к 2-м элементам и результат положить обратно в стек операндов.
  439.                 {
  440.                     while (dictOpsComp[exp[i]] <= ops->a[ops->top - 1].prior && nums->top > 1 || ops->a[ops->top - 1].c == '~' && nums->top >0)  //1 условие на наличие 2 операндов, а второе на унарную операцию
  441.                     {
  442.                         calculate(ops, nums);
  443.                         if (ops->a[ops->top - 1].c == '(' && exp[i] == ')')     //если последняя операция (, а текущая - ), то убрать текущую скобку и удалить левую скобку из стека операций.
  444.                         {
  445.                             deleteBracket(ops);
  446.                             break;
  447.                         }
  448.                     }
  449.  
  450.                     if (exp[i] != ')')                //когда приоритет текущей операции все-таки станет больше последней операции в стеке, добавить текущую операцию в стек.
  451.                     {
  452.                         temp.prior = dictOpsS[exp[i]];
  453.                         temp.c = exp[i];
  454.                         pushOp(ops, temp);
  455.                     }
  456.                 }
  457.             }
  458.  
  459.         }
  460.  
  461.         float res = popNum(nums);
  462.         cout << res;
  463.     }
  464.     else
  465.     {
  466.         cout << "2.Error of input, check brackets or fully of expression\n";
  467.     }
  468.  
  469.     destroysNum(nums);    //освобождение памяти
  470.     destroysOp(ops);
  471.     getch();
  472. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement