Advertisement
Val_Kir

Poliz

Sep 25th, 2016
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.39 KB | None | 0 0
  1. //  записать переменные
  2. //  цикл работы калькулятора
  3. //  считать выражение
  4. //  конвертировать в полиз
  5. //  вычислить его
  6. //  вывести результат
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <ctype.h> //для isdigit и isalpha
  12. struct Node { char k; Node *next;};
  13.  
  14. Node* push(Node *stack, char k) //добавление
  15. {
  16.     Node *head=stack, *nexthead=new Node; //выделяем память для новой вершины
  17.     nexthead->k=k; //в информ. поле вносим значение
  18.     nexthead->next=head; //в поле связи вносим старую вершину
  19.     return nexthead;
  20. }
  21.  
  22. Node* pop(Node *stack,char *k) //удаление c запоминанием
  23. {
  24.     Node *head=stack;
  25.     if(stack==NULL) puts("Empty stack");
  26.     *k=head->k; //запоминаем знач информационного поля
  27.     stack=head->next; //вершина новая
  28.     delete head; //удаляем старую
  29.     return stack;
  30. }
  31.  
  32. Node* delete_head(Node *stack) //удаляет вершину стека
  33. {
  34.     Node *head=stack;
  35.     if(stack==NULL) puts("Empty stack");
  36.     stack=head->next; //новая вершина
  37.     delete head;
  38.     return stack;
  39. }
  40.  
  41. int get_priority(char k) //возвращает приоритет операций, для скобочек вернёт нули, так что их случайно из стека не выкинут
  42. {
  43.     if(k=='+' || k=='-')
  44.         return 1;
  45.     else if(k=='*' || k=='/')
  46.         return 2;
  47.     else return 0;
  48. }
  49.  
  50. int main(void)
  51. {
  52.     int variables[256],nvar,value; //массив переменных, количество, значение
  53.     char namevar,expr[30],poliz[30]; //символ переменной, строка с выражением, строка с полизом
  54.     Node *stack=NULL; //стек
  55.     //читаем переменные
  56.    
  57.     printf("vvedite kolichestvo peremennih\n");
  58.     scanf("%d",&nvar);
  59.     fflush(stdin);
  60.     printf("vvedite peremennie\n"); // первое число, второе название переменной
  61.     for(int i=0;i<nvar;++i)
  62.     {
  63.         scanf("%d %c", &value, &namevar); //такой странный порядок, потому что он хз почему, но поганит ввод, если читать символ первым, может ты лучше придумешь
  64.         variables[namevar]=value; //char - тоже число, только размером в байт, его можно использовать как индекс в массиве
  65.         //так мы заносим значения переменных в массив, и также вытаскиваем
  66.         //printf("%c %d\n", namevar, variables[namevar]);
  67.     }
  68.    
  69.     while(1) //вечный цикл вычисления, на каждой итерации вычисляет строку с выражением
  70.     {
  71.         puts("virajenie\n");
  72.         scanf("%s",expr);
  73.        
  74.         int j=0; //счётчик для передвижения по строке с будущим полизом
  75.         for(int i=0;i<strlen(expr);i++) //пробегаем по каждому символу в выражении
  76.         {
  77.             if(!isdigit(expr[i]) && !isalpha(expr[i])) //если символ не число и не буква переменной, то
  78.             {
  79.                 if(stack==NULL || expr[i]=='(') //если текущий символ скобочка или стек пустой, то пихаем символ в стек
  80.                 {
  81.                     stack=push(stack,expr[i]); //оператор
  82.                 }
  83.                 else if(expr[i]==')') //если закрывающая скобка - выкидываем из стека в полиз все операторы до открывающей скобки
  84.                 {
  85.                     while(stack!=NULL && stack->k!='(')
  86.                         stack=pop(stack,&poliz[j++]);
  87.                    stack=delete_head(stack); //после этого на вершине остаётся открывающая скобка, удаляем её
  88.                 }
  89.                 else
  90.                 {
  91.                     while(stack!=NULL && get_priority(expr[i])<=get_priority(stack->k)) //иначе выкидывам из стека в полиз все операции, что выше
  92.                         stack=pop(stack,&poliz[j++]);   //или равны текущей
  93.                     stack=push(stack,expr[i]); //а саму операцию закидываем на стек
  94.                 }
  95.             }
  96.             else poliz[j++]=expr[i]; //а если это таки число или переменная, то кидаем сразу в полиз
  97.             poliz[j]='\0';  //вот эти 2 строки показывают, как полиз растёт, можно и удалить
  98.             puts(poliz);
  99.         }
  100.        
  101.         while(stack!=0) //тут выкидываем из стека в полиз оставшиеся операторы  
  102.             stack=pop(stack,&poliz[j++]);
  103.        
  104.         poliz[j]='\0'; //ставим нулевой символ в конце и выводим полиз
  105.         puts(poliz);
  106.        
  107.         char a,b; //переменные для хранения чисел, с которыми будем проводить действия
  108.         for(int i=0; i<j; ++i)//проходим по каждому полиза
  109.         {
  110.             if(isalpha(poliz[i])) // если буква
  111.             {
  112.                 stack=push(stack,(char)variables[poliz[i]]);
  113.                 //то вытаскиваем значение переменной из массива, и приводим к типу char чтобы влез в структуру стека, и пихаем на вершину стека
  114.             }
  115.             else if(isdigit(poliz[i])) //если число
  116.                 stack=push(stack,poliz[i]-48); //то приводим его к числу- в строке с полизом не само число, а его символ по ascii таблице
  117.                 //чтобы сделать из символа число, нужно просто отнять 48 т.к 48 символ в таблиц - 0
  118.            
  119.                 //дальше разбираем арифметические операции, везде просто достаём два числа из стека в переменные,
  120.                 //делаем дела и кладём результат на стек
  121.             else if(poliz[i]=='+')
  122.             {
  123.                 stack=pop(stack,&a);
  124.                 stack=pop(stack,&b);
  125.                 stack=push(stack,a+b);
  126.             }
  127.             else if(poliz[i]=='-')
  128.             {
  129.                 stack=pop(stack,&a);
  130.                 stack=pop(stack,&b);
  131.                 stack=push(stack,b-a);
  132.             }
  133.             else if(poliz[i]=='*')
  134.             {
  135.                 stack=pop(stack,&a);
  136.                 stack=pop(stack,&b);
  137.                 stack=push(stack,a*b);
  138.             }
  139.             else if(poliz[i]=='/')
  140.             {
  141.                 stack=pop(stack,&a);
  142.                 stack=pop(stack,&b);
  143.                 stack=push(stack,b/a);
  144.             }
  145.         }
  146.         printf("%d\n",(int)stack->k); //после всех операций результат остаётся в стеке. выводим его и удаляем
  147.         stack=delete_head(stack);
  148.     }
  149.     return 0;
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement