重学数据结构006——中缀表达式转后缀表达式

来源:互联网 发布:图章制作软件在线 编辑:程序博客网 时间:2024/05/01 03:33
 

    我们在数学中常见的计算式,例如2+(3*4)叫做中缀表达式。表达式中涉及到了多个运算符,而运算符之间是有优先级的。计算机在计算并且处理这种表达式时,需要将中缀表达式转换成后缀表达式,然后再进行计算。

    中缀表达式转后缀表达式遵循以下原则:

    1.遇到操作数,直接输出;

    2.栈为空时,遇到运算符,入栈;

    3.遇到左括号,将其入栈;

    4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;

    5.遇到其他运算符'+''-''*''/'时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;

    6.最终将栈中的元素依次出栈,输出。

    经过上面的步骤,得到的输出既是转换得到的后缀表达式。

    举例:a+b*c+(d*e+f)*g    ---------> abc*+de*f+g*+

遇到a,直接输出:

遇到+,此时栈为空,入栈:

遇到b,直接输出:

遇到*,优先级大于栈顶符号优先级,入栈:

遇到c,输出:

遇到+,目前站内的*与+优先级都大于或等于它,因此将栈内的*,+依次弹出并且输出,并且将遇到的这个+入栈:

遇到(,将其入栈:

遇到d,直接输出:

遇到*,由于*的优先级高于处在栈中的(,因此*入栈:

遇到e,直接输出:

遇到+,栈顶的*优先级高于+,但是栈内的(低于+,将*出栈输出,+入栈:

遇到f,直接输出:

 

遇到),弹出栈顶元素并且输出,直到弹出(才结束,在这里也就是弹出+输出,弹出(不输出:

遇到*,优先级高于栈顶+,将*入栈:

遇到g,直接输出:

此时已经没有新的字符了,依次出栈并输出操作直到栈为空:

明白了这个过程,现在就需要用代码实现了。对于各种运算符的优先级,可以使用整数来表示运算符的级别。可以定义一个函数来返回各种符号的优先级数字:

  1. /***************************************************************** 
  2. *根据字符该字符是否在栈中,返回该字符的优先级。 
  3. *这里只处理+、-、*、/、(、)这些符号。 
  4. *需要注意的是:如果(在栈中,它的优先级是最低的,不在栈中则是最高的 
  5. *@param c:需要判断的字符 
  6. *@param flag:字符是否在栈中,0表示在栈中,1表示不在栈中 
  7. *****************************************************************/ 
  8. int GetPrecedence(char c,int flag) 
  9.     if(c=='+' || c=='-'
  10.     { 
  11.         return 1; 
  12.     } 
  13.     else if(c=='*' || c=='/'
  14.     { 
  15.         return 2; 
  16.     } 
  17.     else if(c=='(' && flag==0) 
  18.     { 
  19.         return 0; 
  20.     } 
  21.     else if(c=='(' && flag==1) 
  22.     { 
  23.         return 3; 
  24.     } 
  25.     else 
  26.     { 
  27.         fprintf(stderr,"Input char is invalid!\n"); 
  28.         return -1; 
  29.     } 

 还可以定义一个函数来判断当前遇到的是运算符还是操作数:

  1. /**************************************************************** 
  2. *判断一个字符是不是运算符 
  3. *如果是合法的运算符+、-、*、/、(、)则返回0,否则返回1 
  4. ****************************************************************/ 
  5. int IsOperator(char c) 
  6.     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'
  7.     { 
  8.         return 0; 
  9.     } 
  10.     else 
  11.     { 
  12.         return 1; 
  13.     } 

完整代码:

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #define ElementType char 
  4.  
  5. typedef struct Node *PtrToNode; 
  6. typedef PtrToNode Stack; 
  7. typedef struct Node 
  8.     ElementType Element; 
  9.     PtrToNode Next; 
  10. }; 
  11.  
  12. int IsEmpty(Stack S); 
  13. Stack CreateStack(); 
  14. void DisposeStack(Stack S); 
  15. void MakeEmpty(Stack S); 
  16. void Push(ElementType X,Stack S); 
  17. ElementType Top(Stack S); 
  18. void Pop(Stack S); 
  19.  
  20. //判断栈是否为空 
  21. int IsEmpty(Stack S) 
  22.     return S->Next == NULL; 
  23. //创建链栈 
  24. Stack CreateStack() 
  25.     Stack S = malloc(sizeof(struct Node)); 
  26.     if(S == NULL) 
  27.     { 
  28.         printf("No enough memory!"); 
  29.         return NULL; 
  30.     } 
  31.     S->Next = NULL; 
  32.     MakeEmpty(S); 
  33.     return S; 
  34. //清空栈 
  35. void MakeEmpty(Stack S) 
  36.     if(S == NULL) 
  37.     { 
  38.         printf("Use CreateStack First!"); 
  39.     } 
  40.     else 
  41.     { 
  42.         while(!IsEmpty(S)) 
  43.         { 
  44.             Pop(S); 
  45.         } 
  46.     } 
  47. //进栈 
  48. void Push(ElementType X,Stack S) 
  49.     PtrToNode Tmp; 
  50.     Tmp = malloc(sizeof(struct Node)); 
  51.     if(Tmp != NULL) 
  52.     { 
  53.         Tmp->Element = X; 
  54.         Tmp->Next = S->Next; 
  55.         S->Next = Tmp; 
  56.     } 
  57.     else 
  58.     { 
  59.         printf("Out of space!"); 
  60.     } 
  61. //出栈 
  62. void Pop(Stack S) 
  63.      
  64.     if(IsEmpty(S)) 
  65.     { 
  66.         printf("The Stack is Empty!"); 
  67.     } 
  68.     else 
  69.     { 
  70.         PtrToNode Tmp = S->Next; 
  71.         S->Next = Tmp->Next; 
  72.         free(Tmp); 
  73.     } 
  74. //返回栈顶元素 
  75. ElementType Top(Stack S) 
  76.     if(IsEmpty(S)) 
  77.     { 
  78.         printf("The stack is empty!"); 
  79.         return 0; 
  80.     } 
  81.     else 
  82.     { 
  83.         return S->Next->Element; 
  84.     } 
  85.  
  86. /***************************************************************** 
  87. *根据字符该字符是否在栈中,返回该字符的优先级。 
  88. *这里只处理+、-、*、/、(、)这些符号。 
  89. *需要注意的是:如果(在栈中,它的优先级是最低的,不在栈中则是最高的 
  90. *@param c:需要判断的字符 
  91. *@param flag:字符是否在栈中,0表示在栈中,1表示不在栈中 
  92. *****************************************************************/ 
  93. int GetPrecedence(char c,int flag) 
  94.     if(c=='+' || c=='-'
  95.     { 
  96.         return 1; 
  97.     } 
  98.     else if(c=='*' || c=='/'
  99.     { 
  100.         return 2; 
  101.     } 
  102.     else if(c=='(' && flag==0) 
  103.     { 
  104.         return 0; 
  105.     } 
  106.     else if(c=='(' && flag==1) 
  107.     { 
  108.         return 3; 
  109.     } 
  110.     else 
  111.     { 
  112.         fprintf(stderr,"Input char is invalid!\n"); 
  113.         return -1; 
  114.     } 
  115.  
  116. /**************************************************************** 
  117. *判断一个字符是不是运算符 
  118. *如果是合法的运算符+、-、*、/、(、)则返回0,否则返回1 
  119. ****************************************************************/ 
  120. int IsOperator(char c) 
  121.     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'
  122.     { 
  123.         return 0; 
  124.     } 
  125.     else 
  126.     { 
  127.         return 1; 
  128.     } 
  129.  
  130. char Output[50]; 
  131. //中缀表达式转成后缀表达式 
  132. char* InfixToPostfix(char *ch,Stack S) 
  133.      
  134.     int index=0; 
  135.     char c; 
  136.     while((c=*ch) != '\0'
  137.     { 
  138.         //不是运算符,将该字符放进输出字符数组中。 
  139.         if(IsOperator(c)==1) 
  140.         { 
  141.             Output[index++] = c; 
  142.             ch++; 
  143.         } 
  144.         //是运算符 
  145.         else 
  146.         { 
  147.             //如果此时栈为空,运算符进栈 
  148.             if(IsEmpty(S)) 
  149.             { 
  150.                 Push(c,S); 
  151.                 ch++; 
  152.                 continue
  153.             } 
  154.             else 
  155.             { 
  156.                 if(c==')')   
  157.                 { 
  158.                     while(!IsEmpty(S) && Top(S) != '('
  159.                     { 
  160.                         Output[index++] = Top(S); 
  161.                         Pop(S); 
  162.                     } 
  163.                     Pop(S); 
  164.                     ch++; 
  165.                     continue
  166.                 } 
  167.                 else 
  168.                 { 
  169.                     int outPrecedence = GetPrecedence(c,1); 
  170.                     while(!IsEmpty(S) && GetPrecedence(Top(S),0) >= outPrecedence) 
  171.                     { 
  172.                         Output[index++] = Top(S); 
  173.                         Pop(S); 
  174.                     } 
  175.                     Push(c,S); 
  176.                     ch++; 
  177.                     continue
  178.                 } 
  179.             } 
  180.         } 
  181.     } 
  182.     while(!IsEmpty(S)) 
  183.     { 
  184.         Output[index++] = Top(S); 
  185.         Pop(S); 
  186.     } 
  187.     Output[index] = '\0'
  188.     return Output; 
  189.  
  190.  
  191.  
  192. int main(void
  193.     Stack S = CreateStack(); 
  194.     char *charSequence = "1+2*3+(4*5+6)*7"
  195.     char tmp; 
  196.     char *out = InfixToPostfix(charSequence,S); 
  197.      
  198.      
  199.     while((tmp=*out)!='\0'
  200.     { 
  201.         printf("%c ",tmp); 
  202.         out++; 
  203.     } 
  204.     printf("\n"); 
  205.     return 0; 

 

原创粉丝点击