中缀表达式转后缀表达式

转自:点击打开链接


我们在数学中常见的计算式,例如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.     }  
  31. }  

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

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;  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值