栈实现综合计算器(中缀表达式)
Posted niujifei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈实现综合计算器(中缀表达式)相关的知识,希望对你有一定的参考价值。
实现综合计算器(中缀表达式)
1、使用栈来实现综合计算器
2、思路分析(示意图)
3、代码实现
1 public class Calcuator
2
3 public static void main(String[] args)
4 // 根据前面思路,完成表达式的运算
5 String expression = "3+2*6-2";
6
7 //创建两个栈,数栈,符号栈
8 ArrayStack2 numStack = new ArrayStack(10);
9 ArrayStack2 operStack = new ArrayStack(10);
10
11 //定义需要的相关变量,扫描表达式的索引
12 int index = 0;
13 int num1 = 0;
14 int num2 = 0;
15 int oper = 0;
16 int res = 0;
17 char ch = ‘ ‘; // 将每次扫描得到的 char保存到ch
18 String keepNum = ""; //用于拼接多位数
19
20 //开始用while循环扫描 expression
21 while(true)
22 //依次得到 expression 的每一个字符
23 ch = expression.substring(index, index+1).charAt(0);
24 //判断ch是什么,然后做相应的处理
25 if(operStack.isOper(ch)) //如果是运算符
26 // 判断当前符号栈是否为空
27 if(!operStack.isEmpty())
28 //如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符
29 //在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
30 if(operStack.priority(ch) <= operStack.priority(operStack.peek()) )
31 //
32 num1 = numStack.pop();
33 num2 = numStack.pop();
34 oper = operStack.pop();
35 res = numStack.cal(num1, num2, oper);
36 //运算结果如数栈
37 numStack.push(res);
38 //当前操作符如符号栈
39 operStack.push(ch);
40 else
41 // 如果当前的操作符的优先级大于栈中的操作符,就直接入栈
42 operStack.push(ch);
43
44 else
45 //如果为空,直接入栈
46 operStack.push(ch);
47
48 else
49 // 如果扫描是数字,就直接入数栈
50 // numStack.push(ch - 48); 处理两位数字
51 // 思路分析
52 // 1.当处理多位数时,不能发现是一个数就立即入栈,可能是多位数
53 // 2.在处理数时,需要向 expression 的表达式的 index 后再看以为,如果是数就进行扫描,如果是符号才入栈
54 // 3.因此定义一个变量,用于拼接
55
56 //处理多位数
57 keepNum += ch;
58
59 if(index == expression.length()-1)
60 // 判断ch是否为最后一位,如果是,直接入栈
61 numStack.push(Integer.parseInt(keepNum));
62 else
63
64 //判断下一个字符是不是数字,如果是数字,就继续扫描,如果是运算符,则入栈
65 // 注意只是看后一位,不是index++
66
67 if(operStack.isOper(expression.substring(index+1, index+2).charAt(0)))
68 // 如果后一位是运算符,则入栈
69 numStack.push(Integer.parseInt(keepNum));
70 // 重要!!!清空 keepNum
71 keepNum = "";
72
73
74
75
76 // 让 index + 1,并判断是否扫描到expression最后
77 index++;
78 if(index >= expression.length())
79 break;
80
81
82
83 //当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运行
84 while(true)
85 // 如果符号栈为空,则计算到最后结果,数栈中只有一个数字【结果】
86 if(operStack.isEmpty())
87 break;
88
89 num1 = numStack.pop();
90 num2 = numStack.pop();
91 oper = operStack.pop();
92 res = numStack.cal(num1, num2, oper);
93 numStack.push(res); // 入栈
94
95 // 将数栈的最后数,pop出来
96 System.out.printf("表达式%s = %d\\n",expression,numStack.pop());
97
98
99
100
101 // 创建一个栈,直接使用前面创建好
102 //定义一个ArrayStack 表示栈,扩展功能
103 class ArrayStack
104 private int maxSize; // 栈的大小
105 private int[] stack; // 数组,数组模拟栈,数据就在该数组
106 private int top = -1; // top 表示栈顶,初始化为 -1
107
108 // 构造器
109 public ArrayStack(int maxSize)
110 this.maxSize = maxSize;
111 stack = new int[this.maxSize];
112
113
114 // 判断栈满
115 public boolean isFull()
116 return top == maxSize - 1;
117
118
119 // 判断栈空
120 public boolean isEmpty()
121 return top == -1;
122
123
124 // 入栈 - push
125 public void push(int value)
126 // 先判断栈是否满
127 if (isFull())
128 System.out.println("栈满");
129 return;
130
131 top++;
132
133 stack[top] = value;
134
135
136
137 // 出栈 - pop,将栈顶的数据返回
138 public int pop()
139 // 先判断栈是否空
140 if (isEmpty())
141 // 抛出异常来处理
142 throw new RuntimeException("栈空,没有数据··");
143
144
145 int value = stack[top];
146 top--;
147 return value;
148
149
150 // 显示栈的情况[遍历栈],从栈顶往下显示数据
151 public void list()
152 if (isEmpty())
153 System.out.println("栈空,没有数据~~");
154 return;
155
156
157 for (int i = top; i >= 0; i--)
158 System.out.printf("stack[%d]=%d\\n", i, stack[i]);
159
160
161
162 // 返回运算符的优先级,优先级是程序员来确定的,优先级使用数字表示,
163 // 数字越大,则优先级越高
164 public int priority(int oper)
165 if(oper == ‘*‘ || oper == ‘/‘)
166 return 1;
167 else if (oper == ‘+‘ || oper == ‘-‘)
168 return 0;
169 else
170 return -1; // 假定目前的表达式只有,+,-,*,/
171
172
173
174 // 判断是不是一个运算符
175 public boolean isOper(char val)
176 return val == ‘+‘ || val ==‘-‘ || val == ‘*‘ ||val == ‘/‘;
177
178
179 // 计算方法
180 public int cal(int num1,int num2,int oper)
181 int res = 0; //res 用于存放计算的结果
182 switch(oper)
183 case ‘+‘:
184 res = num1 + num2;
185 break;
186 case ‘-‘:
187 res = num2 - num1; // 注意顺序
188 break;
189 case ‘*‘:
190 res = num1 * num2;
191 break;
192 case ‘/‘:
193 res = num2 / num1;
194 break;
195 default:
196 break;
197
198 return res;
199
200
201 // 增加一个方法,可以返回当前栈顶的值,不是真正的pop
202 public int peek()
203 return stack[top];
204
205
以上是关于栈实现综合计算器(中缀表达式)的主要内容,如果未能解决你的问题,请参考以下文章