// test20.cpp : Defines the entry point for the console application.
//

 #include "stdafx.h"
 #include<iostream>
 #include<stack>
 #include<string>
using namespace std;

class PostExp{
public:
     PostExp(string str):evalStr(str){}
     int evaluate();
private:
     string evalStr;
     stack<int> postStack;
 };

/**


算式中的数字限定在0~9,因为是通过string分别读取每一个元素,如89被认定为8和9
如果操作数要扩大到9以上,则应该用数组保存算式中的每一个元素
此处为方便起见,只是为了表达后缀表达式的基本算法

*/
int PostExp::evaluate(){//后缀表达式计算
    for(string::iterator iter=evalStr.begin(); iter!=evalStr.end(); iter++){//从前至后读取
        int x,y,z;
         if(*iter>='0' && *iter<='9')
             postStack.push(*iter - '0');//如果读到数字,压栈
        else{//如果读到操作符,出栈两个操作数,并计算
            y=postStack.top();//y保存操作符右边的数字
            postStack.pop();
             x=postStack.top();//x保存操作符左边的数字
            postStack.pop();
             switch(*iter){
                     case '+': z=x+y; break;//z保存计算结果
                    case '-' : z=x- y; break;
                     case '*': z=x*y; break;
                     case '/' : z=x/y;  break;
             }
             postStack.push(z);//把计算结果作为操作数压栈
        }
     }
     return postStack.top();
 }

int main(){
     PostExp* pe=new PostExp("352*5+-");
     cout<<pe->evaluate();
     system("pause");
 }
=================




一、后缀表达式介绍



后缀表达式的特点就是计算机运算非常方便,需要用到栈;计算机处理过程只需要顺序读入,如果遇到数字,则放入栈中,如果是运算符,则将两个栈中数字取出进行运算;

比如1+2的后缀表达式为12+;

而栈可以把一般的中缀表达式变成后缀表达式,并且计算后缀表达式得出结果,因此此应用在计算器中非常常用;


二、中缀表达式转换成后缀表达式



此方法需要遵循几个规则:

(1)如果读入操作数,则直接放入输出字符串;

(2)如果读入一般运算符如+-*/,则放入堆栈,但是放入堆栈之前必须要检查栈顶,并确定栈顶运算符的优先级比放入的运算符的优先级低;如果放入的优先级较低,则需要将栈顶的运算符放入输出字符串;

(3)如果读入(,因为左括号优先级最高,因此放入栈中,但是注意,当左括号放入栈中后,则优先级最低;

(4)如果读入),则将栈中运算符取出放入输出字符串,直到取出(为止,注意:()不输出到输出字符串;

(5)顺序读完表达式,如果栈中还有操作符,则弹出,并放入输出字符串;

  

三、计算后缀表达式




规则如下:

(1)如果是操作数,则放入栈中;

(2)如果是操作符,则取出栈中两个操作数,进行运算后,将结果放入栈中;

(3)直到最后栈中只有一个元素,此元素就是计算结果;

 

四、代码



以下代码是计算器的辅助代码,通过此代码可以快速进行计算。

输入: 四则运算(支持括号)

输出:结果字符串



[java] view plain copy print ?


1. package
2.   
3. import
4.   
5.   
6.   
7. /**
8.  * 计算器工具类
9.  * 完成整数、浮点的加、减、乘、除、括号运算
10.  * 
11.  * 禁忌:如果出现.5表示0.5,则结果不正确
12.  * @author xiazdong
13.  *
14.  */
15. public class
16. /**
17.      * 将中缀表达式转换成后缀表达式 规则: 1.如果是操作数,则添加到输出流 2.如果是(,则添加栈中;
18.      * 3.如果是),则将栈中操作符移入输出流,直到(为止,()不添加入输出流 4.如果是一般操作符(+-*
19.      * /),则加入栈之前,需要检查栈中的操作符的优先级,如果栈顶优先级比添加的优先级高,则将栈顶操作符移入输出流,否则直接添加操作符;
20.      */
21.       
22. public static
23. return
24.     }  
25.       
26. private static
27. // 1.创建Stack 
28. new
29. // 2.创建输出流字符串 
30. new
31. // 3.解析中缀表达式 
32. // 3.1 如果是读到数字,则接着读,直到读到操作符为止 
33. for (int i = 0, numLenCount = 1; i < str.length(); i += numLenCount) {  
34. char
35. "";  
36. 1;  
37. if ((ch + "").matches("\\d{1}")) {  
38. 1;  
39. char nextChar = 0;  
40. if ((i + numLenCount) < str.length()) { // 下一个字符是否超过边界长度 
41.                     nextChar = str.charAt(i + numLenCount);  
42. while ((nextChar + "").matches("[.\\d{1}]")) {  
43.                         operand += nextChar;  
44. if ((i + numLenCount + 1) < str.length()) {  
45. 1);  
46.                             numLenCount++;  
47. else
48.                             numLenCount++;  
49. break;  
50.                         }  
51.                     }  
52.                 }  
53. " ";  
54.                 builder.append(operand);  
55.   
56. else
57. if (ch == '(') {  
58. "");  
59. else if (ch == '+' || ch == '-') {  
60. while (s.size() > 0 && s.peek().matches("[-+*/]")) {  
61. " ");  
62.                     }  
63. "");  
64. else if (ch == '*' || ch == '/') {  
65. while (s.size() > 0 && s.peek().matches("[*/]")) {  
66. " ");  
67.                     }  
68. "");  
69. else if (ch == ')') {  
70. while (s.size() > 0 && !s.peek().equals("(")) {  
71. " ");  
72.                     }  
73.                     s.pop();  
74.                 }  
75.             }  
76.         }  
77. while (s.size() > 0) {  
78. " ");  
79.         }  
80.         System.out.println(builder);  
81. return
82.   
83.     }  
84.   
85. /**
86.      * 计算后缀表达式
87.      * 
88.      */
89. private static
90.   
91. " ");  
92. new
93. for (int i = 0; i < splitStr.length; i++) {  
94.             String ch = splitStr[i];  
95. if (ch.matches("\\d+.\\d+")||ch.matches("\\d+")) {  
96.                 s.push(ch);  
97. else
98. if (s.size() >= 2) {  
99.                     String c1 = s.pop();  
100.                     String c2 = s.pop();  
101. if (ch.equals("+")) {  
102. if(c1.contains(".")||c2.contains(".")){  
103. "") + Double  
104. ""))));  
105.                         }  
106. else{  
107. "") + Integer  
108. ""))));  
109.                         }  
110.                           
111. else if ("-".equals(ch)) {  
112. if(c1.contains(".")||c2.contains(".")){  
113. "") - Double  
114. ""))));  
115.                         }  
116. else{  
117. "") - Integer  
118. ""))));  
119.                         }  
120. else if ("*".equals(ch)) {  
121. if(c1.contains(".")||c2.contains(".")){  
122. "") * Double  
123. ""))));  
124.                         }  
125. else{  
126. "") * Integer  
127. ""))));  
128.                         }  
129. else if ("/".equals(ch)) {  
130. "") / Double  
131. ""))));  
132.                     }  
133.   
134. else
135. "式子有问题!");  
136. return null;  
137.                 }  
138.             }  
139.         }  
140. return
141.     }  
142. }