`
tubaluer
  • 浏览: 1447820 次
文章分类
社区版块
存档分类
最新评论
  • sblig: c / c++ 是不一样的都会输出 100
    j = j++

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

 
阅读更多

我们在数学中常见的计算式,例如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. *@paramc:需要判断的字符
  6. *@paramflag:字符是否在栈中,0表示在栈中,1表示不在栈中
  7. *****************************************************************/
  8. intGetPrecedence(charc,intflag)
  9. {
  10. if(c=='+'||c=='-')
  11. {
  12. return1;
  13. }
  14. elseif(c=='*'||c=='/')
  15. {
  16. return2;
  17. }
  18. elseif(c=='('&&flag==0)
  19. {
  20. return0;
  21. }
  22. elseif(c=='('&&flag==1)
  23. {
  24. return3;
  25. }
  26. else
  27. {
  28. fprintf(stderr,"Inputcharisinvalid!\n");
  29. return-1;
  30. }
  31. }

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

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

完整代码:

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics