Advertisement
kirya_shkolnik

Pokish Notation

Feb 12th, 2023
1,001
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.51 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. #define MAX_EXPRESSION_LENGTH 100  // Максимальная длина выражения
  7. #define MAX_TOKEN_LENGTH 20        // Максимальная длина каждого токена в выражении
  8. #define STACK_SIZE 100             // Максимальная длина стэка
  9. #define PI 3.14159265
  10.  
  11. // Токены - Перечисление всех типов токенов в выражении
  12. #define VALUE_ 0
  13. #define PLUS_ 1
  14. #define MINUS_ 2
  15. #define MULTIPLY_ 3
  16. #define DIVIDE_ 4
  17. #define POW_ 5
  18. #define SIN_ 6
  19. #define COS_ 7
  20. #define TAN_ 8
  21. #define L_PAREN_ 9
  22. #define R_PAREN_ 10
  23.  
  24. // Token structure - структура для хранения каждого токена в выражении
  25. typedef struct {
  26.     int type;             // Тип токена (например, число, оператор, функция и т.д.)
  27.     double value;         // Если тип токена число -- используем валуе
  28.     char symbol[MAX_TOKEN_LENGTH]; // Если тип токена не число -- записываем в строку (например, "+", cos)
  29. } Token;
  30.  
  31. // Stack structure -  структура для хранения стека токенов
  32.  
  33. // Вообще не понимаю что в этом стеке происходит
  34. typedef struct {
  35.     Token data[STACK_SIZE];  // Массив токенов
  36.     int top;                 // Сколько у нас элементов массива
  37. } Stack;
  38.  
  39. // Некоторые функции закоменченные. Они были либо лагучими, либо из разных кодов, либо не нужные, крч бесполезный высер
  40. void initializeStack(Stack *stack);
  41. int isStackEmpty(Stack *stack);
  42. void push(Stack *stack, Token token);
  43. Token pop(Stack *stack);
  44. Token getTop(Stack *stack);
  45. //int getStackSize(Stack *stack);
  46.  
  47. void parseExpression(char * expression, Stack *stack);
  48. void translateToRPN(Stack *inputStack, Stack *outputStack);
  49. //double calculateRPN(Stack *stack);
  50. //void displayGraph(double (*func)(double), double start, double end, double step);
  51.  
  52. // Инициалзиация стека
  53. void initializeStack(Stack *stack) {
  54.     stack->top = -1;  // Ставим топ -1 (супер странная реализация стека конечно)
  55. }
  56.  
  57. // Стэк пустой
  58. int isStackEmpty(Stack *stack) {
  59.     return stack->top == -1;  
  60. }
  61.  
  62. void push(Stack *stack, Token token) {
  63.     stack->data[++stack->top] = token;  
  64. }
  65.  
  66. Token pop(Stack *stack) {
  67.     return stack->data[stack->top--];  }
  68.  
  69. Token peek(Stack *stack) {
  70.   return stack->data[stack->top];
  71. }
  72.  
  73. int getStackSize(Stack *stack) {
  74.   return stack->top + 1;
  75. }
  76.  
  77. // Разбираем выражение в стэк токенов
  78. void parseExpression(char * expression, Stack *stack) {
  79.   Token token;
  80.   int i, j;
  81.   int length = (int) strlen(expression);
  82.   char number[MAX_TOKEN_LENGTH];
  83.  
  84.   initializeStack(stack);
  85.  
  86.   for (i = 0, j = 0; i < length; i++) {
  87.       // Если число
  88.     if ((expression[i] >= 48 && expression[i]<=57) || expression[i] == '.') {
  89.       number[j++] = expression[i];
  90.     } else {
  91.         // Если `j` больше 0 (указывает на то, что было сформировано число)
  92.       if (j > 0) {
  93.         number[j] = '\0';
  94.         j = 0;
  95.  
  96.         token.type = VALUE_;
  97.           char* end;
  98.           // char to double
  99.         token.value = strtod(number, &end);
  100.         push(stack, token);
  101.       } else if (expression[i] == 'x') {// Если икс то валуе 0
  102.         token.type = VALUE_;
  103.         token.value = 0;
  104.         push(stack, token);
  105.       }
  106.  
  107.       //Оператор Switch для обработки различных типов символов в строке выражения
  108.       switch (expression[i]) {
  109.         case '+':
  110.           token.type = PLUS_;
  111.           strcpy(token.symbol, "+");
  112.           push(stack, token);
  113.           break;
  114.         case '-':
  115.           token.type = MINUS_;
  116.           strcpy(token.symbol, "-");
  117.           push(stack, token);
  118.           break;
  119.         case '*':
  120.           token.type = MULTIPLY_;
  121.           strcpy(token.symbol, "*");
  122.           push(stack, token);
  123.           break;
  124.         case '/':
  125.           token.type = DIVIDE_;
  126.           strcpy(token.symbol, "/");
  127.           push(stack, token);
  128.           break;
  129.         case '^':
  130.           token.type = POW_;
  131.           strcpy(token.symbol, "^");
  132.           push(stack, token);
  133.           break;
  134.         case 's':
  135.           if (expression[i + 1] == 'i' && expression[i + 2] == 'n') {
  136.             token.type = SIN_;
  137.             strcpy(token.symbol, "sin");
  138.             push(stack, token);
  139.             i += 2;
  140.           }
  141.           break;
  142.         case 'c':
  143.           if (expression[i + 1] == 'o' && expression[i + 2] == 's') {
  144.             token.type = COS_;
  145.             strcpy(token.symbol, "cos");
  146.             push(stack, token);
  147.             i += 2;
  148.           }
  149.           break;
  150.         case 't':
  151.           if (expression[i + 1] == 'a' && expression[i + 2] == 'n') {
  152.             token.type = TAN_;
  153.             strcpy(token.symbol, "tan");
  154.             push(stack, token);
  155.             i += 2;
  156.           }
  157.           break;
  158.         case '(':
  159.           token.type = L_PAREN_;
  160.           strcpy(token.symbol, "(");
  161.           push(stack, token);
  162.           break;
  163.         case ')':
  164.           token.type = R_PAREN_;
  165.           strcpy(token.symbol, ")");
  166.           push(stack, token);
  167.           break;
  168.         default:
  169.           break;
  170.       }
  171.     }
  172.   }
  173.  
  174.   if (j > 0) {
  175.     number[j] = '\0';
  176. //    j = 0;
  177.  
  178.     token.type = VALUE_;
  179.       char* end;
  180.     token.value = strtod(number, &end);
  181.     push(stack, token);
  182.   }
  183. }
  184.  
  185. // Из стэка всех символов собираем стэк в обратной полской нотации
  186. void translateToRPN(Stack *inputStack, Stack *outputStack) {
  187.   Stack operatorStack;
  188.   Token token, topToken;
  189.  
  190.   initializeStack(outputStack);
  191.   initializeStack(&operatorStack);
  192.  
  193.   while (!isStackEmpty(inputStack)) {
  194.     token = pop(inputStack);
  195.  
  196.     switch (token.type) {
  197.       case VALUE_:
  198.         push(outputStack, token);
  199.         break;
  200.       case PLUS_:
  201.       case MINUS_:
  202.       case MULTIPLY_:
  203.       case DIVIDE_:
  204.       case POW_:
  205.       case SIN_:
  206.       case COS_:
  207.       case TAN_:
  208.         while (!isStackEmpty(&operatorStack) &&
  209.                getTop(&operatorStack).type >= token.type) {
  210.           topToken = pop(&operatorStack);
  211.           push(outputStack, topToken);
  212.         }
  213.  
  214.         push(&operatorStack, token);
  215.         break;
  216.       case L_PAREN_:
  217.         push(&operatorStack, token);
  218.         break;
  219.       case R_PAREN_:
  220.         topToken = pop(&operatorStack);
  221.  
  222.         while (topToken.type != L_PAREN_) {
  223.           push(outputStack, topToken);
  224.           topToken = pop(&operatorStack);
  225.         }
  226.  
  227.         break;
  228.       default:
  229.         break;
  230.     }
  231.   }
  232.  
  233.   while (!isStackEmpty(&operatorStack)) {
  234.     topToken = pop(&operatorStack);
  235.     push(outputStack, topToken);
  236.   }
  237. }
  238.  
  239. // Вычисление в обратной польской нотации
  240. double evaluateRPN(Stack *stack) {
  241.   double value1, value2;
  242.   Token token, topToken;
  243.  
  244.   Stack valueStack;
  245.   initializeStack(&valueStack);
  246.  
  247.   while (!isStackEmpty(stack)) {
  248.     token = pop(stack);
  249.  
  250.     switch (token.type) {
  251.       case VALUE_:
  252.         push(&valueStack, token);
  253.         break;
  254.       case PLUS_:
  255.         value2 = pop(&valueStack).value;
  256.         value1 = pop(&valueStack).value;
  257.         push(&valueStack, (Token){ VALUE_, value1 + value2 });
  258.         break;
  259.       case MINUS_:
  260.         value2 = pop(&valueStack).value;
  261.         value1 = pop(&valueStack).value;
  262.         push(&valueStack, (Token){ VALUE_, value1 - value2 });
  263.         break;
  264.       case MULTIPLY_:
  265.         value2 = pop(&valueStack).value;
  266.         value1 = pop(&valueStack).value;
  267.         push(&valueStack, (Token){ VALUE_, value1 * value2 });
  268.         break;
  269.       case DIVIDE_:
  270.         value2 = pop(&valueStack).value;
  271.         value1 = pop(&valueStack).value;
  272.         push(&valueStack, (Token){ VALUE_, value1 / value2 });
  273.         break;
  274.       case POW_:
  275.         value2 = pop(&valueStack).value;
  276.         value1 = pop(&valueStack).value;
  277.         push(&valueStack, (Token){ VALUE_, pow(value1, value2) });
  278.         break;
  279.       case SIN_:
  280.         value1 = pop(&valueStack).value;
  281.         push(&valueStack, (Token){ VALUE_, sin(value1) });
  282.         break;
  283.       case COS_:
  284.         value1 = pop(&valueStack).value;
  285.         push(&valueStack, (Token){ VALUE_, cos(value1) });
  286.         break;
  287.       case TAN_:
  288.         value1 = pop(&valueStack).value;
  289.         push(&valueStack, (Token){ VALUE_, tan(value1) });
  290.         break;
  291.       default:
  292.         break;
  293.     }
  294.   }
  295.  
  296.   return pop(&valueStack).value;
  297. }
  298.  
  299. void printRPN(Stack *stack) {
  300.     int i;
  301.     Token token;
  302.     for (i = 0; i <= stack->top; i++) {
  303.         token = stack->data[i];
  304.         if (token.type == VALUE_) {
  305.             if(token.value == 0){
  306.  
  307.             printf("x ");
  308.             }else
  309.             printf("%.1lf ", token.value);
  310.         } else {
  311.             printf("%s ", token.symbol);
  312.         }
  313.     }
  314.     printf("\n");
  315. }
  316. int main(int argc, char *argv[]) {
  317.     Stack inputStack, outputStack;
  318.  
  319.   parseExpression("2+3*x", &inputStack);
  320.   translateToRPN(&inputStack, &outputStack);
  321.     printRPN(&outputStack);
  322.  
  323.   return 0;
  324. }
  325.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement