中缀表达式转后缀表达式

 我们在数学中常见的计算式,例如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,直接输出:

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

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

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

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

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

        完整的代码如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值