Advertisement
Guest User

Untitled

a guest
Dec 28th, 2013
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.08 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstring>
  3.  
  4. using namespace std;
  5.  
  6.  
  7. #define MAX_LEN 256
  8. typedef struct
  9. {
  10.     char mas[10];
  11. }stack; //
  12.  
  13. void push(stack *_stack, int &_ptr, char data[]);
  14. void pop(stack *_stack, int &_ptr, char *data, int enter);
  15. int pow_int(int a,int b);
  16. void push_int(int *_stack, int &_ptr, int data);
  17. int pop_int(int *_stack, int &_ptr);
  18.  
  19.  
  20. //  Преобразование записи математ. выражения из инфиксной в постфиксную (в обратную польскую запись) и вычисление данного выражения
  21. //
  22. //  Сразу оговоримся, допустимые операторы: +,-,*,/,(,),^; все операции будем считать лево-ассоциативными
  23. //  Все операнды - односимвольные
  24. //
  25. void PostfixNotation(const char *_infix, char *_postfix)
  26. {
  27.     stack stack[100];
  28.     int st_ptr = 0;             // указатель вершины стека
  29.     int out_index = 0;      // индекс в выходной строке
  30.     int in_index = 0;       // индекс во входной строке
  31.     for(int i = 0; i < 100; i++)
  32.     {
  33.         for(int j = 0; j < 10; j++)
  34.             stack[i].mas[i] = 0;
  35.     }
  36.     // начинаем разбор входящей строки (она не должна быть пустой)
  37.     do
  38.     {
  39.         char c[1];  // берем текущий символ входной строки
  40.         c[0] = _infix[in_index];
  41.         int j = 0;
  42.         switch (c[0])
  43.         {
  44.             case '+':
  45.             case '-':
  46.                 // выталкиваем из стека в выходную строку все операторы с большим или равным приоритетом
  47.                 while (st_ptr != 0)
  48.                 {
  49.                     char op = stack[st_ptr-1].mas[0];   // оператор в вершине стека
  50.                     if (op != '(')  // все операторы, кроме откр. скобки имеют больший или равный приоритет
  51.                     {
  52.                         _postfix[out_index++] = op; // добавляем оператор в выходную строку
  53.                         pop(stack, st_ptr, 0, 0);           // удаляем оператор из стека
  54.                     }
  55.                     else
  56.                         break;
  57.                 }
  58.                 // помещаем оператор в стек
  59.                 push(stack, st_ptr, c);
  60.                 break;
  61.  
  62.             case '*':
  63.             case '/':
  64.                 // выталкиваем из стека в выходную строку все операторы с большим или равным приоритетом
  65.                 while (st_ptr != 0)
  66.                 {
  67.                     char op = stack[st_ptr-1].mas[0];
  68.                     if ((op == '^') || (op == '*') || (op == '/'))
  69.                     {
  70.                         _postfix[out_index++] = op; // добавляем оператор в выходную строку
  71.                         pop(stack, st_ptr, 0, 0);           // удаляем оператор из стека
  72.                     }
  73.                     else
  74.                         break;
  75.                 }
  76.                 // помещаем оператор в стек
  77.                 push(stack, st_ptr, c);
  78.                 break;
  79.  
  80.             case '(':
  81.                 // просто помещаем в стек
  82.                 push(stack, st_ptr, c);
  83.                 break;
  84.  
  85.             case ')':
  86.                 // выталкиваем из стека в выходную строку все элементы до открывающей скобки (откр. скобку просто отбрасываем)
  87.                 while (st_ptr != 0)
  88.                 {
  89.                     char* op;
  90.                     pop(stack, st_ptr,op,0);    // забираем из стека оператор
  91.                     if (op[0] == '(')                   // если достигли открывающей скобки
  92.                         break;                      // выталкивание закончили
  93.                     else
  94.                     {
  95.                         _postfix[out_index++] = op[0];  // добавили оператор в выходную строку
  96.                     }
  97.                 }
  98.                 break;
  99.  
  100.             case '^':
  101.                 // помещаем оператор в стек (выталкивать ничего не нужно, нет операторов с большим приоритетом)
  102.                 push(stack, st_ptr, c);
  103.                 break;
  104.  
  105.             default:        // символ цифры
  106.                 _postfix[out_index] = c[0]; // добавляем цифру в выходную строку
  107.                 out_index++;
  108.                 break;
  109.         }
  110.  
  111.         in_index++; // переходим к следующему символу входной строки
  112.     }
  113.     while (_infix[in_index] != 0);  // разбор закончен
  114.  
  115.     // выталкиваем все операторы в выходную строку
  116.     while(st_ptr != 0)
  117.         pop(stack, st_ptr, _postfix, out_index);
  118.  
  119.  
  120.     // завершающий символ нуля
  121.     //_postfix[out_index] = 0;
  122. }
  123.  
  124. int calculation(const char* postfix, int x)
  125. {
  126.     int stack[MAX_LEN]; // стек для хранения операндов
  127.     int st_ptr = 0;     // указатель вершины стека
  128.  
  129.     int temp,temp1; // Временная переменна
  130.     int in_index = 0; // Счетчик массива постфиксной записи
  131.  
  132.     int op_a, op_b; // Переменные для вычисления выражения
  133.  
  134.     do
  135.     {
  136.         char c = postfix[in_index];
  137.         if (((c >= '0') && (c <= '9')) || c == 'x') // Если число
  138.         {
  139.             if(c == 'x')
  140.                 temp = x;
  141.             else
  142.                 temp = c - '0';
  143.         }
  144.         else
  145.         {
  146.             op_b = pop_int(stack, st_ptr); // Выталкиваем два оператора из стека
  147.             op_a = pop_int(stack, st_ptr);
  148.  
  149.             switch(c) // Производим операции в зависимости от операнда и записываем их во временную переменную
  150.             {
  151.                 case '+':
  152.                     temp = op_a + op_b;
  153.                     break;
  154.                 case '-':
  155.                     temp = op_a - op_b;
  156.                     break;
  157.                 case '*':
  158.                     temp = op_a * op_b;
  159.                     break;
  160.                 case '/':
  161.                     temp = op_a / op_b;
  162.                     break;
  163.                 case '^':
  164.                     temp = pow_int(op_a, op_b);
  165.                     break;
  166.                 default:
  167.                     cout << "Unknown operation " << c << endl;
  168.                     exit(EXIT_FAILURE);
  169.             }
  170.         }
  171.         push_int(stack, st_ptr, temp); // Кладем на вершину стека временную переменную, переходим к следующему символу постфиксной записи
  172.         in_index++;
  173.     }
  174.     while(postfix[in_index] != 0);
  175.  
  176.     return pop_int(stack, st_ptr); // К концу алгоритма на вершине стека будет записан результат вычисления данного выражения
  177. }
  178.  
  179.  
  180.  
  181. void push(stack *_stack, int &_ptr, char data[])
  182. {
  183.     for(int i = 0; i <= strlen(data); i++)
  184.         _stack[_ptr].mas[i] = data[i];
  185.     _ptr++;
  186. }
  187.  
  188. void pop(stack *_stack, int &_ptr, char *data, int enter)
  189. {
  190.     --_ptr;
  191.     for(int i = 0; i <= strlen(_stack[_ptr].mas); i++)
  192.     {
  193.         data[enter++] = _stack[_ptr].mas[i];
  194.         cout << _stack[_ptr].mas[i];
  195.     }
  196. }
  197.  
  198. void push_int(int *_stack, int &_ptr, int data)
  199. {
  200.     _stack[_ptr++] = data;
  201. }
  202.  
  203. int pop_int(int *_stack, int &_ptr)
  204. {
  205.     return _stack[--_ptr];
  206. }
  207.  
  208. int pow_int(int a, int b)
  209. {
  210.     int res = a;
  211.     while (b >= 2)
  212.     {
  213.         res = res * a;
  214.         b--;
  215.     }
  216.     return res;
  217. }
  218.  
  219.  
  220. int main()
  221. {
  222.     char str_infix[] = "3,4+2,8*x";
  223.     char str_postfix[MAX_LEN];
  224.     int result;
  225.     PostfixNotation(str_infix,str_postfix);
  226.     cout << str_postfix;
  227.     result = calculation(str_postfix,42);
  228.     cout << result << endl;
  229.     return 0;
  230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement