Advertisement
Ladies_Man

ExprBuilder (Минимизация количества скобок в арифметическом)

Dec 25th, 2014
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.93 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <cstring>
  4. #include <stdlib.h>
  5. #include <algorithm>
  6.  
  7. using namespace std;
  8.  
  9. int var, tag, num, indx;
  10. string image, number;
  11.  
  12. struct stack {
  13.     int data[100];
  14.     int top;
  15. };
  16.  
  17. void InitStack (struct stack *s)
  18. {
  19.     s->top = 0;
  20. }
  21. int pop (struct stack *s)
  22. {
  23.     return s->data[--s->top];
  24. }
  25. void push (struct stack *s, int x)
  26. {
  27.     s->data[s->top++] = x;
  28. }
  29. int show (struct stack *s)
  30. {
  31.     int retval = s->data[--s->top];
  32.     s->data[s->top++] = retval;
  33.     return retval;
  34. }
  35.  
  36. void parse_E (string str, struct stack *s);
  37. void parse_E1 (string str, struct stack *s);
  38. void parse_T (string str, struct stack *s);
  39. void parse_T1 (string str, struct stack *s);
  40. void parse_F (string str, struct stack *s);
  41.  
  42. int prior (const char *str, int x)
  43. {
  44.     if (str[x] == '+' || str[x] == '-') return 1;
  45.     if (str[x] == '*' || str[x] == '/') return 2;
  46. }
  47.  
  48. int sign (const char *str, int x)
  49. {
  50.     if (str[x] == '+') return 1;
  51.     if (str[x] == '-') return 2;
  52.     if (str[x] == '*') return 3;
  53.     if (str[x] == '/') return 4;
  54. }
  55.  
  56. int myatoi(string string_str)
  57. {
  58.     const char * char_str = string_str.c_str();
  59.     int val = 0;
  60.     while( *char_str ) val = val*10 + (*char_str++ - '0');
  61.     return val;
  62. }
  63.  
  64. void NextLexem (string str)
  65. {
  66.     int jndx = 0;
  67.     while (indx < str.size()) {
  68.         if ('_' != str[indx]) {
  69.             if (str[indx] == '+') {
  70.                 image = '+';
  71.             } else if (str[indx] == '-') {
  72.                 image = '-';
  73.                 } else if (str[indx] == '*') {
  74.                     image = '*';
  75.                     } else if (str[indx] == '/') {
  76.                         image = '/';
  77.                         } else if (str[indx] == '(') {
  78.                             image = '(';
  79.                             } else if (str[indx] == ')') {
  80.                                 image = ')';
  81.                             }
  82.             tag = 1;
  83.             if (str[indx] == 'x') {
  84.                 tag = 2;
  85.                 image = 'x';
  86.             }
  87.             jndx = indx;
  88.             if ((str[indx] >= '0') && (str[indx] <= '9')) {
  89.                 tag = 3;
  90.                 number = "";
  91.                 while ((jndx < str.size()) && (str[jndx] >= '0') && (str[jndx] <= '9')) {
  92.                     number += str[jndx];
  93.                     jndx++;
  94.                 }
  95.                 indx = jndx - 1;
  96.             }
  97.         } else {
  98.             indx++;
  99.             continue;
  100.         }
  101.         indx++;
  102.         break;
  103.     }
  104.  
  105. }
  106.  
  107. void parse_E (string str, struct stack *s)
  108. {
  109.     parse_T (str, s);
  110.     parse_E1 (str, s);
  111. }
  112.  
  113. void parse_T (string str, struct stack *s)
  114. {
  115.     parse_F (str, s);
  116.     parse_T1 (str, s);
  117. }
  118.  
  119. void parse_E1 (string str, struct stack *s)
  120. {
  121.     if ((tag == 1) && (image == "-")) {
  122.         NextLexem(str); //next lexem for <T>
  123.         parse_T(str, s);   //<T>
  124.         int arg1 = pop(s), arg2 = pop(s);
  125.         push(s, arg2 - arg1);
  126.         parse_E1(str, s);  //<E1>
  127.     } else if ((tag == 1) && (image == "+")) {
  128.         NextLexem(str);
  129.         parse_T(str, s);
  130.         push(s, pop(s) + pop(s));
  131.         parse_E1(str, s);
  132.         }
  133. }
  134.  
  135. void parse_T1 (string str, struct stack *s)
  136. {
  137.     if ((tag == 1) && (image == "/")) {
  138.         NextLexem(str); //next lexem for <F>
  139.         parse_F(str, s);   //<F>
  140.         int arg1 = pop(s), arg2 = pop(s);
  141.         push(s, arg2 / arg1);
  142.         parse_T1(str, s);  //<T1>
  143.     } else if (tag == 1 && image == "*") {
  144.         NextLexem(str);
  145.         parse_F(str, s);
  146.         push(s, pop(s) * pop(s));
  147.         parse_T1(str, s);
  148.         }
  149. }
  150.  
  151. void parse_F (string str, struct stack *s)
  152. {
  153.     if (tag == 1) {
  154.         if (image == "-") {
  155.             NextLexem(str);
  156.             parse_F(str, s);
  157.             push(s, pop(s) * (-1));
  158.         } else if (image == "(") {
  159.             NextLexem(str); //next lexem for <E>
  160.             parse_E(str, s);   //( <E> )
  161.             NextLexem(str);
  162.         }
  163.     } else if (tag == 2) {
  164.             push(s, var);
  165.             NextLexem(str);
  166.             } else if (tag == 3) {
  167.                     push(s, myatoi(number));
  168.                     NextLexem(str);
  169.             }
  170. }
  171.  
  172. string lucky (string expr)
  173. {
  174.     const char * str = expr.c_str();
  175.     int i, delnum = 0;
  176.     for (i = 0; i <= strlen(str); i++)
  177.         if (str[i] == '(' || str[i] == ')') expr.erase(i - delnum++, 1);
  178.     return expr;
  179. }
  180.  
  181. string del_unary_n_extrenal (string expr)
  182. {
  183.     const char * str = expr.c_str();
  184.     int i, j, buf = 0;
  185.     for (i = strlen(str); i >= 0; i--) {
  186.         if ((str[i] == '-' || str[i] == '+' || str[i] == '*' || str[i] == '/') && str[i+1] == '(' && str[i+3] == ')') {
  187.             expr.erase(i+3, 1);
  188.             expr.erase(i+1, 1);
  189.         }
  190.     }
  191.  
  192.     const char * str_no_unary = expr.c_str();
  193.     if (str_no_unary[0] == '(' && str_no_unary[strlen(str_no_unary)-1] == ')') {
  194.         for (i = 0; i <= strlen(str_no_unary); i++) {
  195.             if (str_no_unary[i] == '(') buf++;
  196.             if (str_no_unary[i] == ')') buf--;
  197.             if (buf == 0) break;
  198.             if (i == strlen(str_no_unary) - 2 && buf == 1) {
  199.                 expr.erase(strlen(str_no_unary)-1,1);
  200.                 expr.erase(0, 1);
  201.             }
  202.         }
  203.     }
  204.     return expr;
  205. }
  206.  
  207. void del_brackets (string expr)
  208. {
  209.     const char * str = expr.c_str();
  210.     int i, j, k, buf, prior1, prior2, sign1, sign2, delnum = 0;
  211.     for (i = 0; i < expr.size(); i++) {
  212.         if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') {
  213.             prior1 = prior(str, i);
  214.             sign1 = sign(str, i);
  215.             if (str[i-1] == ')') {
  216.                     buf = 0;
  217.                     j = i - 1;
  218.                     while (j >=0) {
  219.                         if (str[j] == '(') buf++;
  220.                         if (str[j] == ')') buf--;
  221.                         if (buf == 0) break;
  222.                         j--;
  223.                     }
  224.                     if (buf == 0) {
  225.                             for (k = i - 1; k >= j; k--) {
  226.                                     prior2 = 2;
  227.                                 if (str[k] == '+') {
  228.                                     prior2 = 1;
  229.                                     sign2 = 1;
  230.                                     break;
  231.                                 }
  232.                                 if (str[k] == '-') {
  233.                                     prior2 = 1;
  234.                                     sign2 = 2;
  235.                                     break;
  236.                                 }
  237.                                 if (str[k] == '*' || str[k] == '/') prior2 = 2;
  238.                             }
  239.                             if (prior2 == 2 || (prior1 == 1 && sign2 == 1) || (prior1 == 1 && sign2 == 2)) {
  240.                                     expr.erase(j, 1);
  241.                                     delnum++;
  242.                                     expr.erase(i-1-delnum++,1);
  243.                             }
  244.                     }
  245.                 }
  246.             if (str[i+1] == '(') {
  247.                     buf = 0;
  248.                     j = i + 1;
  249.                     while (j <= strlen(str)) {
  250.                         if (str[j] == '(') buf++;
  251.                         if (str[j] == ')') buf--;
  252.                         if (buf == 0) break;
  253.                         j++;
  254.                     }
  255.                     if (buf == 0) {
  256.                             for (k = i+1; k <= j; k++) {
  257.                                     prior2 = 2;
  258.                                 if (str[k] == '+') {
  259.                                     prior2 = 1;
  260.                                     sign2 = 1;
  261.                                     break;
  262.                                 }
  263.                                 if (str[k] == '-') {
  264.                                     prior2 = 1;
  265.                                     sign2 = 2;
  266.                                     break;
  267.                                 }
  268.                                 if (str[k] == '*' || str[k] == '/') prior2 = 2;
  269.                             }
  270.                             if (sign1 == 1 || (sign1 == 2 && prior2 == 2) || (prior1 == 2 && prior2 == 2)) {
  271.                                     expr.erase(i+1-delnum++, 1);
  272.                                     expr.erase(j-delnum++,1);
  273.                             }
  274.                     }
  275.                 }
  276.         }
  277.     }
  278.     cout << expr << endl;
  279. }
  280.  
  281. void parse (string expr1)
  282. {
  283.     struct stack sm1;
  284.     indx = 0;
  285.     number = "";
  286.     InitStack(&sm1);
  287.     NextLexem(expr1);
  288.     parse_E(expr1, &sm1);
  289.     cout << show(&sm1) << endl;
  290.  
  291.     struct stack sm2;
  292.     indx = 0;
  293.     number = "";
  294.     InitStack(&sm2);
  295.     string expr2 = lucky(expr1);
  296.     NextLexem(expr2);
  297.     parse_E(expr2, &sm2);
  298.  
  299.     if (show(&sm1) == show(&sm2)) {
  300.         cout << expr2 << endl;
  301.         return;
  302.     }
  303.     del_brackets (del_unary_n_extrenal(expr1));
  304. }
  305.  
  306. int main()
  307. {
  308.     string expr;
  309.     cin >> expr;
  310.     cin >> var;
  311.     parse(expr);
  312.     return 0;
  313. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement