LarvitarYoung

V2_evaluate_expression

Apr 25th, 2021 (edited)
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.04 KB | None | 0 0
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<stdbool.h>
  5. #include<math.h>
  6. #include<ctype.h>
  7. typedef struct stack{
  8.     union {
  9.         float number;
  10.         char operatorToken;
  11.     }Template;
  12.     struct stack *next;
  13. }stack;
  14. void push(stack **dest,stack *holder){
  15.     holder->next=*dest;
  16.     *dest=holder;
  17. }
  18. stack pop(stack **src){
  19.     stack *temp=*src;
  20.     *src=(*src)->next;
  21.     return *temp;
  22. }
  23. stack *createStack(){
  24.     stack *newStack = malloc(sizeof(stack));
  25.     return newStack;
  26. }
  27. bool isEmpty(stack *src){
  28.     if(src==NULL){return true;}
  29.     return false;
  30. }
  31. int priority(char token,bool inStack){
  32.     if(inStack&&token=='('){return 0;}
  33.     switch(token){
  34.         case '+': case '-':return 1;
  35.         case '*': case '/':return 2;
  36.         case '(': case '%': return 3;
  37.         case '^':case '#':case '@':  return 4;
  38.     }
  39. }
  40. float evaluate(char *postfix){
  41.     float prev,next;
  42.     int token=-1;
  43.     stack *numberStack=createStack();
  44.     numberStack=NULL;
  45.     stack *holder=NULL;
  46.     while(postfix[++token]!='\0'){
  47.         holder=createStack();
  48.         if(isdigit(postfix[token])){
  49.             holder->Template.number=(float)(postfix[token]-'0');
  50.             push(&numberStack,holder);
  51.         }
  52.         else{
  53.             switch(postfix[token]){
  54.                 case '+':
  55.                     holder->Template.number=pop(&numberStack).Template.number+pop(&numberStack).Template.number;
  56.                     push(&numberStack,holder);
  57.                     break;
  58.                 case '-':
  59.                     next=pop(&numberStack).Template.number;
  60.                     prev=pop(&numberStack).Template.number;
  61.                     holder->Template.number=prev-next;
  62.                     push(&numberStack,holder);
  63.                     break;
  64.                 case '*':
  65.                     holder->Template.number=pop(&numberStack).Template.number*pop(&numberStack).Template.number;
  66.                     push(&numberStack,holder);
  67.                     break;
  68.                 case '/':
  69.                     next=pop(&numberStack).Template.number;
  70.                     prev=pop(&numberStack).Template.number;
  71.                     holder->Template.number=prev/next;
  72.                     push(&numberStack,holder);
  73.                     break;
  74.                 case '#':
  75.                     numberStack->Template.number*=-1;
  76.                     break;
  77.                 case '@':
  78.                     numberStack->Template.number*=1;
  79.                     break;
  80.                 case '^':
  81.                     next=pop(&numberStack).Template.number;//exponent
  82.                     prev=pop(&numberStack).Template.number;//base
  83.                     holder->Template.number=pow(prev,next);
  84.                     push(&numberStack,holder);
  85.                     break;
  86.                 case '%':
  87.                     /*watch out you can't have % operator on float*/
  88.                     next=pop(&numberStack).Template.number;
  89.                     prev=pop(&numberStack).Template.number;
  90.                     float temp =(int)prev%(int)(next);
  91.                     holder->Template.number=temp;
  92.                     push(&numberStack,holder);
  93.                     break;
  94.             }      
  95.            
  96.         }
  97.     }
  98.     return pop(&numberStack).Template.number;
  99. }
  100. void main(){
  101.     stack *operatorStack=createStack();
  102.     operatorStack=NULL;
  103.     stack *holder=NULL;
  104.     char postfix[256]={};int tokenPostfix=-1;
  105.     char   infix[256]={};int tokenInfix=-1;
  106.     bool operandInfront;
  107.     //fgets(infix,256,stdin);/*input mode*/
  108.     FILE *fp=fopen("cal3.txt","r");
  109.     while(fgets(infix,256,fp)){
  110.         operandInfront=false;
  111.         for(tokenInfix=0;infix[tokenInfix]!='\n';tokenInfix++){
  112.             if(isdigit(infix[tokenInfix])){
  113.                 postfix[++tokenPostfix]=infix[tokenInfix];operandInfront=true;
  114.             }
  115.             else{
  116.                 holder=createStack();
  117.                 if((priority(infix[tokenInfix],false)==1)&&!operandInfront){
  118.                     if(infix[tokenInfix]=='+'){holder->Template.operatorToken='@';}
  119.                     else{holder->Template.operatorToken='#';}
  120.                     push(&operatorStack,holder);
  121.                     operandInfront=false;continue;
  122.                 }
  123.                 if(infix[tokenInfix]==')'){
  124.                     while(operatorStack->Template.operatorToken!='('){
  125.                         postfix[++tokenPostfix]=pop(&operatorStack).Template.operatorToken;
  126.                     }
  127.                     pop(&operatorStack);
  128.                     operandInfront=true;continue;
  129.                 }
  130.                 if(operandInfront&&infix[tokenInfix]=='('){
  131.                     if(isEmpty(operatorStack)){/*bascally do nothing*/}
  132.                     else{
  133.                         while(priority(operatorStack->Template.operatorToken,true)>=priority(infix[tokenInfix],false)){
  134.                             postfix[++tokenPostfix]=pop(&operatorStack).Template.operatorToken;
  135.                             if(isEmpty(operatorStack)){break;}
  136.                         }
  137.                     }
  138.                     holder->Template.operatorToken='*';
  139.                     push(&operatorStack,holder);
  140.                     holder=createStack();
  141.                     holder->Template.operatorToken='(';
  142.                     push(&operatorStack,holder);
  143.                     operandInfront=false;continue;
  144.                 }
  145.                 if(isEmpty(operatorStack)){
  146.                     holder->Template.operatorToken=infix[tokenInfix];
  147.                     push(&operatorStack,holder);
  148.                 }
  149.                 else if(priority(operatorStack->Template.operatorToken,true)>=priority(infix[tokenInfix],false)){
  150.                     do{
  151.                         postfix[++tokenPostfix]=pop(&operatorStack).Template.operatorToken;
  152.                         if(isEmpty(operatorStack)){break;}
  153.                     }while(priority(operatorStack->Template.operatorToken,true)>=priority(infix[tokenInfix],false));
  154.                     holder->Template.operatorToken=infix[tokenInfix];
  155.                     push(&operatorStack,holder);
  156.                 }
  157.                 else{
  158.                     holder->Template.operatorToken=infix[tokenInfix];
  159.                     push(&operatorStack,holder);
  160.                 }
  161.                 operandInfront=false;
  162.             }
  163.         }
  164.         while(!isEmpty(operatorStack)){
  165.             postfix[++tokenPostfix]=pop(&operatorStack).Template.operatorToken;
  166.         }
  167.         printf("%-20s=%.2f\n",postfix,evaluate(postfix));
  168.         memset(postfix,0,256);
  169.         memset(infix,0,256);
  170.         tokenPostfix=-1;
  171.     }
  172. }
Add Comment
Please, Sign In to add comment