Advertisement
alch1337

math_parser

Feb 22nd, 2015
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.42 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5.  
  6. #define CAPACITY 255
  7.  
  8. int is_a_number(char c) {
  9.     return ((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E') ? 1 : 0;
  10. }
  11.  
  12. int op_precendence(char c) {
  13.     switch (c) {
  14.     case '(':
  15.         return 2;
  16.     case '+':
  17.     case '-':
  18.         return 3;
  19.     case '*':
  20.     case '/':
  21.         return 4;
  22.     case '^':       //pow
  23.         return 5;
  24.     case '`':       //sqrt
  25.         //case '~':     //exp              
  26.     case '!':       //log
  27.     case '@':       //sin
  28.     case '#':       //cos
  29.     case '$':       //tan
  30.     case '&':       //sinh
  31.     case '[':       //cosh
  32.     case ']':       //tanh
  33.     case '{':       //asin
  34.     case '}':       //acos
  35.     case ';':       //atan
  36.         return 1;
  37.     default:
  38.         return 0;
  39.     }
  40. }
  41.  
  42. char* convert_to_rpn(char *expr) {
  43.     static char rpn_expr[CAPACITY];
  44.     char stack[CAPACITY];
  45.     char temp[CAPACITY];
  46.     int i, j, k, l, depth;
  47.  
  48.     i = j = k = l = depth = 0;
  49.  
  50.     for (; expr[l] != '\0'; ++l) {
  51.         if (!is_a_number(expr[l])) {
  52.             int p = op_precendence(expr[l]);
  53.             switch (p) {
  54.             case 0:
  55.                 switch (expr[l]) {
  56.                 case ')':
  57.                     if (k) {
  58.                         for (int w = 0; w < k; ++w)
  59.                             rpn_expr[i++] = temp[w];
  60.                         rpn_expr[i++] = ' ';
  61.                         k = 0;
  62.                     }
  63.                     while (stack[--j] != '(' && j >= 0) {
  64.                         rpn_expr[i++] = stack[j];
  65.                         rpn_expr[i++] = ' ';
  66.                     }
  67.                     --depth;
  68.                     break;
  69.                 case ' ':
  70.                     break;
  71.                 default:
  72.                     temp[k++] = expr[l];
  73.                 }
  74.                 break;
  75.             case 2:
  76.                 if (k) {
  77.                     temp[k] = '\0';
  78.                     if (!strcmp(temp, "sqrt")) stack[j++] = '`';
  79.                     //else if (!strcmp(temp, "exp")) stack[j++] = '~';
  80.                     else if (!strcmp(temp, "log")) stack[j++] = '!';
  81.                     else if (!strcmp(temp, "sin")) stack[j++] = '@';
  82.                     else if (!strcmp(temp, "cos")) stack[j++] = '#';
  83.                     else if (!strcmp(temp, "tan")) stack[j++] = '$';
  84.                     else if (!strcmp(temp, "sinh")) stack[j++] = '&';
  85.                     else if (!strcmp(temp, "cosh")) stack[j++] = '[';
  86.                     else if (!strcmp(temp, "tanh")) stack[j++] = ']';
  87.                     else if (!strcmp(temp, "asin")) stack[j++] = '{';
  88.                     else if (!strcmp(temp, "acos")) stack[j++] = '}';
  89.                     else if (!strcmp(temp, "atan")) stack[j++] = ';';
  90.                     k = 0;
  91.                 }
  92.                 else
  93.                     stack[j++] = expr[l];
  94.                 ++depth;
  95.                 break;
  96.             case 3:
  97.             case 4:
  98.             case 5:
  99.                 if (k) {
  100.                     for (int w = 0; w < k; ++w)
  101.                         rpn_expr[i++] = temp[w];
  102.                     rpn_expr[i++] = ' ';
  103.                     k = 0;
  104.                 }
  105.                 while (op_precendence(expr[l]) <= op_precendence(stack[j - 1]) && j > 0) {
  106.                     rpn_expr[i++] = stack[--j];
  107.                     rpn_expr[i++] = ' ';
  108.                 }
  109.                 stack[j++] = expr[l];
  110.                 break;
  111.             case 1:
  112.                 stack[j++] = expr[l];
  113.                 break;
  114.             default:
  115.                 return "";
  116.             }
  117.         }
  118.         else
  119.             temp[k++] = expr[l];
  120.     }
  121.     for (int w = 0; w < k; ++w)
  122.         rpn_expr[i++] = temp[w];
  123.     rpn_expr[i++] = ' ';
  124.     while (j > 0)
  125.         rpn_expr[i++] = stack[--j];
  126.     while (rpn_expr[i] == ' ') --i;
  127.     rpn_expr[i] = '\0';
  128.     return rpn_expr;
  129. }
  130.  
  131. double convert_to_a_number(char *expr) {
  132.     int i, extra, power, temp, sign;
  133.     double num;
  134.     i = num = extra = power = temp = 0;
  135.     sign = 1;
  136.  
  137.     if (expr[i++] == '-')
  138.         sign = -1;
  139.     else
  140.         --i;
  141.  
  142.     while (expr[i] != '\0') {
  143.         if (expr[i] == '.') extra = 1;
  144.         else if (expr[i] == 'e' || expr[i] == 'E') extra = 2;
  145.         else if (extra == 2) {
  146.             if (expr[i++] == '-') extra = -1;
  147.             else extra = 1;
  148.             while (expr[i] != '\0') {
  149.                 temp *= 10;
  150.                 temp += expr[i++] - '0';
  151.             }
  152.         }
  153.         else {
  154.             if (extra == 1) --power;
  155.             num *= 10;
  156.             num += expr[i] - '0';
  157.         }
  158.         ++i;
  159.     }
  160.     power += (extra * temp);
  161.     return sign*num*pow(10, power);
  162. }
  163.  
  164. double calculate(char *rpn_expr) {
  165.     double stack[CAPACITY] = { 0 };
  166.     char temp[CAPACITY];
  167.     int i, j, k;
  168.     double op1, op2;
  169.     i = j = k = op1 = op2 = 0;
  170.  
  171.     while (rpn_expr[i] != '\0') {
  172.         if (is_a_number(rpn_expr[i])) {
  173.             temp[k++] = rpn_expr[i];
  174.         }
  175.         else {
  176.             switch (rpn_expr[i]) {
  177.             case ' ':
  178.                 if (k) {
  179.                     temp[k] = '\0';
  180.                     stack[j++] = convert_to_a_number(temp);
  181.                 }
  182.                 k = 0;
  183.                 break;
  184.             case '+':
  185.                 op1 = stack[--j];
  186.                 op2 = stack[--j];
  187.                 stack[j++] = op2 + op1;
  188.                 break;
  189.             case '-':
  190.                 op1 = stack[--j];
  191.                 op2 = stack[--j];
  192.                 stack[j++] = op2 - op1;
  193.                 break;
  194.             case '*':
  195.                 op1 = stack[--j];
  196.                 op2 = stack[--j];
  197.                 stack[j++] = op2 * op1;
  198.                 break;
  199.             case '/':
  200.                 op1 = stack[--j];
  201.                 op2 = stack[--j];
  202.                 stack[j++] = (double)op2 / op1;
  203.                 break;
  204.             case '`':
  205.                 op1 = stack[--j];
  206.                 stack[j++] = sqrt(op1);
  207.                 break;
  208.             case '!':
  209.                 op1 = stack[--j];
  210.                 stack[j++] = log(op1);
  211.                 break;
  212.             case '@':
  213.                 op1 = stack[--j];
  214.                 stack[j++] = sin(op1);
  215.                 break;
  216.             case '#':
  217.                 op1 = stack[--j];
  218.                 stack[j++] = cos(op1);
  219.                 break;
  220.             case '$':
  221.                 op1 = stack[--j];
  222.                 stack[j++] = tan(op1);
  223.                 break;
  224.             case '&':
  225.                 op1 = stack[--j];
  226.                 stack[j++] = sinh(op1);
  227.                 break;
  228.             case '[':
  229.                 op1 = stack[--j];
  230.                 stack[j++] = cosh(op1);
  231.                 break;
  232.             case ']':
  233.                 op1 = stack[--j];
  234.                 stack[j++] = tanh(op1);
  235.                 break;
  236.             case '{':
  237.                 op1 = stack[--j];
  238.                 stack[j++] = asin(op1);
  239.                 break;
  240.             case '}':
  241.                 op1 = stack[--j];
  242.                 stack[j++] = acos(op1);
  243.                 break;
  244.             case ';':
  245.                 op1 = stack[--j];
  246.                 stack[j++] = atan(op1);
  247.                 break;
  248.             default:
  249.                 return 0;
  250.             }
  251.         }
  252.         ++i;
  253.     }
  254.     if (--j != 0) return 0;
  255.     else return stack[j];
  256.  
  257. }
  258.  
  259. double parse(char *expr) {
  260.     return calculate(convert_to_rpn(expr));
  261. }
  262.  
  263. int main() {
  264.     char line[CAPACITY];
  265.  
  266.     while (strcmp(line, "x")) {
  267.         scanf("%s", line);
  268.         printf("%f\n", parse(line));
  269.     }
  270.  
  271.     getchar();
  272.     return 0;
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement