Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // записать переменные
- // цикл работы калькулятора
- // считать выражение
- // конвертировать в полиз
- // вычислить его
- // вывести результат
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h> //для isdigit и isalpha
- struct Node { char k; Node *next;};
- Node* push(Node *stack, char k) //добавление
- {
- Node *head=stack, *nexthead=new Node; //выделяем память для новой вершины
- nexthead->k=k; //в информ. поле вносим значение
- nexthead->next=head; //в поле связи вносим старую вершину
- return nexthead;
- }
- Node* pop(Node *stack,char *k) //удаление c запоминанием
- {
- Node *head=stack;
- if(stack==NULL) puts("Empty stack");
- *k=head->k; //запоминаем знач информационного поля
- stack=head->next; //вершина новая
- delete head; //удаляем старую
- return stack;
- }
- Node* delete_head(Node *stack) //удаляет вершину стека
- {
- Node *head=stack;
- if(stack==NULL) puts("Empty stack");
- stack=head->next; //новая вершина
- delete head;
- return stack;
- }
- int get_priority(char k) //возвращает приоритет операций, для скобочек вернёт нули, так что их случайно из стека не выкинут
- {
- if(k=='+' || k=='-')
- return 1;
- else if(k=='*' || k=='/')
- return 2;
- else return 0;
- }
- int main(void)
- {
- int variables[256],nvar,value; //массив переменных, количество, значение
- char namevar,expr[30],poliz[30]; //символ переменной, строка с выражением, строка с полизом
- Node *stack=NULL; //стек
- //читаем переменные
- printf("vvedite kolichestvo peremennih\n");
- scanf("%d",&nvar);
- fflush(stdin);
- printf("vvedite peremennie\n"); // первое число, второе название переменной
- for(int i=0;i<nvar;++i)
- {
- scanf("%d %c", &value, &namevar); //такой странный порядок, потому что он хз почему, но поганит ввод, если читать символ первым, может ты лучше придумешь
- variables[namevar]=value; //char - тоже число, только размером в байт, его можно использовать как индекс в массиве
- //так мы заносим значения переменных в массив, и также вытаскиваем
- //printf("%c %d\n", namevar, variables[namevar]);
- }
- while(1) //вечный цикл вычисления, на каждой итерации вычисляет строку с выражением
- {
- puts("virajenie\n");
- scanf("%s",expr);
- int j=0; //счётчик для передвижения по строке с будущим полизом
- for(int i=0;i<strlen(expr);i++) //пробегаем по каждому символу в выражении
- {
- if(!isdigit(expr[i]) && !isalpha(expr[i])) //если символ не число и не буква переменной, то
- {
- if(stack==NULL || expr[i]=='(') //если текущий символ скобочка или стек пустой, то пихаем символ в стек
- {
- stack=push(stack,expr[i]); //оператор
- }
- else if(expr[i]==')') //если закрывающая скобка - выкидываем из стека в полиз все операторы до открывающей скобки
- {
- while(stack!=NULL && stack->k!='(')
- stack=pop(stack,&poliz[j++]);
- stack=delete_head(stack); //после этого на вершине остаётся открывающая скобка, удаляем её
- }
- else
- {
- while(stack!=NULL && get_priority(expr[i])<=get_priority(stack->k)) //иначе выкидывам из стека в полиз все операции, что выше
- stack=pop(stack,&poliz[j++]); //или равны текущей
- stack=push(stack,expr[i]); //а саму операцию закидываем на стек
- }
- }
- else poliz[j++]=expr[i]; //а если это таки число или переменная, то кидаем сразу в полиз
- poliz[j]='\0'; //вот эти 2 строки показывают, как полиз растёт, можно и удалить
- puts(poliz);
- }
- while(stack!=0) //тут выкидываем из стека в полиз оставшиеся операторы
- stack=pop(stack,&poliz[j++]);
- poliz[j]='\0'; //ставим нулевой символ в конце и выводим полиз
- puts(poliz);
- char a,b; //переменные для хранения чисел, с которыми будем проводить действия
- for(int i=0; i<j; ++i)//проходим по каждому полиза
- {
- if(isalpha(poliz[i])) // если буква
- {
- stack=push(stack,(char)variables[poliz[i]]);
- //то вытаскиваем значение переменной из массива, и приводим к типу char чтобы влез в структуру стека, и пихаем на вершину стека
- }
- else if(isdigit(poliz[i])) //если число
- stack=push(stack,poliz[i]-48); //то приводим его к числу- в строке с полизом не само число, а его символ по ascii таблице
- //чтобы сделать из символа число, нужно просто отнять 48 т.к 48 символ в таблиц - 0
- //дальше разбираем арифметические операции, везде просто достаём два числа из стека в переменные,
- //делаем дела и кладём результат на стек
- else if(poliz[i]=='+')
- {
- stack=pop(stack,&a);
- stack=pop(stack,&b);
- stack=push(stack,a+b);
- }
- else if(poliz[i]=='-')
- {
- stack=pop(stack,&a);
- stack=pop(stack,&b);
- stack=push(stack,b-a);
- }
- else if(poliz[i]=='*')
- {
- stack=pop(stack,&a);
- stack=pop(stack,&b);
- stack=push(stack,a*b);
- }
- else if(poliz[i]=='/')
- {
- stack=pop(stack,&a);
- stack=pop(stack,&b);
- stack=push(stack,b/a);
- }
- }
- printf("%d\n",(int)stack->k); //после всех операций результат остаётся в стеке. выводим его и удаляем
- stack=delete_head(stack);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement