Infix-to-suffix expression in DSAA (3)

1. A brief review

  The author believes that the algorithm only needs to remember the process, and the key to remembering the process is to do more multiple-choice questions in the written test, such as
Niuke.com :

write picture description here

  It can be done exactly according to the algorithm of converting infix expressions to postfix expressions:

step stack postfix expression
encounter X output null X
encounter = push = X
encounter A output = FAR
encounter A output = FAR
Encounter +, higher priority than =, push into the stack =+ FAR
encounter B output =+ XAB
When * is encountered, it has higher priority than + and is pushed into the stack =+* XAB
Encountered (, directly into the stack =+*( XAB
encounter C output =+*( XABC
Encountered -, the top of the stack is (, pushed onto the stack =+*(- XABC
encounter D output =+*(- XABCD
Encountered), throw all operators on the stack until (, and discard () =+* XABCD-
Encounter /, the top of the stack is , throw it directly , then encounter +, the priority is lower than /, push into the stack / =+/ XABCD-*
encounter E output =+/ XABCD- * E
When NULL is encountered, throw all elements in the stack null XABCD- * AND / + =

2. Algorithm implementation

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <string.h>
#include <ctype.h>
#define MAXSTACKSIZE 20
#define MAXSIZE  50
#define  handle_error(msg) do{ perror(msg); exit(-1);}while(0);
typedef   char TYPE;

typedef struct stack{
   int stacksize;
   int topofstack;
   TYPE  * arrary;
} STACK;

void destroy_stack();
TYPE pop();
TYPE top();
int push(TYPE );
STACK * creat_stack(int );
char * transfer_expression(char * );
int handle_experession(char *, char * );
STACK * ptr;


int main(void){
   char infixexpression[MAXSIZE];
   char * result;
   ptr=creat_stack(MAXSTACKSIZE);

   //获取表达式
   if(fgets(infixexpression,MAXSIZE,stdin) == NULL)
      errx(1, "gets error\n");
   result=transfer_expression(infixexpression);

   free(result);
   destroy_stack(ptr);
}


char * transfer_expression(char * infixexpression){
  char * ptr;
  if((ptr=calloc(strlen(infixexpression), sizeof(char))) == NULL)
     handle_error("malloc");
  handle_experession(infixexpression,ptr);
  printf("%s\n",ptr);
  return ptr;
}

int handle_experession(char * infixexpression, char * result){
    if(*infixexpression == '\n'||*infixexpression == '\0'){
       for(;top() != -1;){
            //debug
            //printf("out %c\n",top());
            *result++=pop();
       }
       return 0;
    }
    else if(isalnum(*infixexpression) != 0)
       *result++=*infixexpression;
    else
       switch(*infixexpression){
          case '*':
          case '/':
              for(;top() != -1;)
                  if(top() != '*' && top() != '/' || top() == '('){
                      push(*infixexpression);
                      //debug
                      //printf("in %c\n",top());
                      goto exit1;
                  }
                  else{
                      //debug
                      //printf("out %c\n",top());
                      *result++=pop();
                  }
              push(*infixexpression);
              //debug
              //printf("in %c\n",top());
              exit1: 
                  break;
          case '+':
          case '-':
              for(;top() != -1;)
                  if(top() == '('|| top() == '='){
                      push(*infixexpression);
                      //debug
                      //printf("in %c\n",top());
                      goto exit2;
                  }
                  else{
                      //printf("out %c\n",top());
                      *result++=pop();
                  }
              push(*infixexpression);
              //debug
              //printf("in %c\n",top());
              exit2:
                  break;
          case '(':
              push(*infixexpression);
              //debug
              //printf("in %c\n",top());
              break;
          case ')':
              do{
                 printf("out %c\n",top());
                 *result++=pop();
              }while(top() != '(');
              //debug
              //printf("pop %c\n",top());
              pop();
              break;
          case '=':
              for(;top() != -1;){
                  //debug
                  //printf("out %c\n",top());
                  *result++=pop();
              }
              push(*infixexpression);
              //debug
              //printf("in %c\n",top());
              break;
       }
       return handle_experession(infixexpression+1,result);
}



STACK * creat_stack(int stacksize){
   STACK * ptr;
   if((ptr=malloc(sizeof(STACK))) == NULL)
      handle_error("malloc");
   ptr->stacksize=stacksize;
   ptr->topofstack=-1;
   if((ptr->arrary=malloc(stacksize*sizeof(TYPE))) == NULL)
      handle_error("malloc");
   return ptr;
}

int push(TYPE value){
   if(ptr->topofstack== ptr->stacksize)
      return -1;
   (ptr->arrary)[++ptr->topofstack]=value;
   return 0;
}


TYPE pop(){
   if(ptr->topofstack== -1)
      return -1;
   return (ptr->arrary)[ptr->topofstack--];
}

TYPE top(){
   if(ptr->topofstack== -1)
      return -1;
   return (ptr->arrary)[ptr->topofstack];
}


void destroy_stack(){
   if(ptr != NULL){
      free(ptr->arrary);
      free(ptr);
   }
}

  result:

[root@localhost ~]# ./3_3
x=a+b*(c-d)/e       #这里是输入的中缀表达式
xabcd-*e/+=
[root@localhost ~]# ./3_3
4*5+3*(6*9)/5       #这里是输入的中缀表达式
45*369**5/+
[root@localhost ~]# 

3. Review

  The author handle_experession's implementation of , uses a recursive approach. The biggest feeling is debugthe importance. We can't guarantee that the code you enter once will run 100%. There are always some small details wrong, resulting in different results than expected. Therefore, you must force yourself to consider debugthe point setting when programming.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324770719&siteId=291194637