3o_3v

calculator

Dec 21st, 2021 (edited)
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.60 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4.  
  5. typedef struct list {
  6.     struct list *next;
  7.     enum {
  8.         OP,
  9.         VAL
  10.     } type;
  11.     union {
  12.         char c;
  13.         long long v;
  14.     };
  15. } list;
  16.  
  17. int isempty(list *s) {
  18.     return s->next == NULL;
  19. }
  20.  
  21. list *new_list(unsigned char type) {
  22.     list *new = malloc(sizeof(list));
  23.     new->type = type;
  24.     new->next = NULL;
  25.     return new;
  26. }
  27.  
  28. list *push(list *s, char c, long long v) {
  29.     if (s == NULL) {
  30.         return NULL;
  31.     }
  32.     list *new = malloc(sizeof(list));
  33.     new->next = s;
  34.     if (s->type == OP) {
  35.         new->type = OP;
  36.         new->c = c;
  37.         return new;
  38.     } else {
  39.         new->type = VAL;
  40.         new->v = v;
  41.         return new;
  42.     }
  43. }
  44.  
  45. list *pop(list *s) {
  46.     if (s == NULL) return NULL;
  47.     if (s->next == NULL) {
  48.         free(s);
  49.         return NULL;
  50.     } else {
  51.         list *new = s->next;
  52.         free(s);
  53.         return new;
  54.     }
  55. }
  56.  
  57. static inline int isnum(char c) {
  58.     return c >= '0' && c <= '9';
  59. }
  60.  
  61. static inline int isop(char c) {
  62.     return c == '*' || c == '/' || c == '+' || c == '-' || c == '(' || c == ')';
  63. }
  64.  
  65. int prio(char c) {
  66.     if (c == '(')
  67.         return 0;
  68.     if (c == '+' || c == '-')
  69.         return 1;
  70.     if (c == '*' || c == '/')
  71.         return 2;
  72.     return -1;
  73. }
  74.  
  75. long long makeop(long long a, long long b, char c) {
  76.     if (c == '+') {
  77.         return a + b;
  78.     }
  79.     if (c == '-') {
  80.         return a - b;
  81.     }
  82.     if (c == '*') {
  83.         return a*b;
  84.     }
  85.     if (c == '/') {
  86.         return a/b;
  87.     }
  88.     return 0;
  89. }
  90.  
  91. int main(void) {
  92.     list *op = new_list(0);
  93.     list *nums = new_list(1);
  94.     long long accum = 0;
  95.     char *str = "1-(2+3)*2-2*(1+1)/2";
  96.     int i = 0;
  97.     while (str[i] != '\0') {
  98.         if (isnum(str[i])) {
  99.             while (isnum(str[i]) && str[i] != '\0') {
  100.                 accum *= 10;
  101.                 accum += str[i++] - '0';
  102.             }
  103.             nums = push(nums, 0, accum);
  104.             accum = 0;
  105.         } else if (isop(str[i])) {
  106.             if (str[i] == '(') {
  107.                 op = push(op, '(', 0);
  108.                 i++;
  109.             } else if (str[i] == ')') {
  110.                 while (op->c != '(') {
  111.                     long long a, b;
  112.                     b = nums->v;
  113.                     nums = pop(nums);
  114.                     a = nums->v;
  115.                     nums = pop(nums);
  116.                     long long c = makeop(a, b, op->c);
  117.                     op = pop(op);
  118.                     nums = push(nums, 0, c);
  119.                 }
  120.                 op = pop(op);
  121.                 i++;
  122.             } else if (isempty(op) || prio(str[i]) > prio(op->c)) {
  123.                 op = push(op, str[i++], 0);
  124.             } else {
  125.                 while (!isempty(op) && prio(str[i]) <= prio(op->c)) {
  126.                     long long a, b;
  127.                     b = nums->v;
  128.                     nums = pop(nums);
  129.                     a = nums->v;
  130.                     nums = pop(nums);
  131.                     long long c = makeop(a, b, op->c);
  132.                     op = pop(op);
  133.                     nums = push(nums, 0, c);
  134.                 }
  135.                 op = push(op, str[i++], 0);
  136.             }
  137.         }
  138.     }
  139.     while (!isempty(op)) {
  140.         long long a, b;
  141.         b = nums->v;
  142.         nums = pop(nums);
  143.         a = nums->v;
  144.         nums = pop(nums);
  145.         long long c = makeop(a, b, op->c);
  146.         op = pop(op);
  147.         nums = push(nums, 0, c);
  148.     }
  149.     long long res = nums->v;
  150.     printf("%lld", res);
  151.     free(op);
  152.     while (nums) {
  153.         nums = pop(nums);
  154.     }
  155. }
Add Comment
Please, Sign In to add comment