使用栈求得简单表达式的值
例:100+100/5-4等类似的式子,式中仅包含加减乘除,不包括小括号。所用栈由数组模拟实现。
实现思路
定义两个栈,一个用来存放数值,一个用来存放符号。
- 使用
while循环对整个式子进行扫描。 - 当判断该字符为数字时:继续往后判断直到遇到符号时,对先前扫描过的字符保留有在字符串中的位置,进行截取并存储到数值栈中。
- 当判断该字符为符号时,
- 如果符号栈为空,则直接将该字符压入栈,继续扫描。
- 如果符号栈不为空,则要判断目前的符号和栈顶符号的优先级,如果符号栈顶的符号优先级较高,则将其取出,并且取出数值栈中的前两个元素(这里注意取数值的顺序,以免运算错误)进行计算,然后将计算后的数值重新压入数值栈中,最后将目前扫描到的符号压入符号栈中。如果扫描到的符号优先级高于符号栈顶的符号,则直接将符号压入符号栈
- 上述过程会持续到字符串扫描结束,此时如果符号栈不为空,则要从数值栈中取两个数值、符号栈中取出一个符号进行计算,重复该操作直到符号栈为空。此时数值栈中仅有一个元素为最终结果。
代码实现(java)
public class Stack_calu {
public static void main(String[] args) {
Stack stack_value = new Stack(10);
Stack stack_symbol = new Stack(10);
String express = "100+100/5-4";
int index = 0;
while ( index < express.length() ) {
if (symbol(express.charAt(index))) {
int end = index + 1;
while (end < express.length() - 1 && symbol(express.charAt(end))) {
end++;
}
String value = express.substring(index, end);
stack_value.push(value);
index = end;
} else {
if (!stack_symbol.isEmpty()) {
if (priority(String.valueOf(express.charAt(index))) <= priority(stack_symbol.getTop())) {
String num2 = stack_value.pop();
String num1 = stack_value.pop();
String sym = stack_symbol.pop();
int num = makeCalculate(num2, num1, sym.charAt(0));
stack_value.push(String.valueOf(num));
}
}
stack_symbol.push(String.valueOf(express.charAt(index)));
index++;
}
}
while (!stack_symbol.isEmpty()) {
String num2 = stack_value.pop();
String num1 = stack_value.pop();
String sym = stack_symbol.pop();
int num = makeCalculate(num2, num1, sym.charAt(0));
stack_value.push(String.valueOf(num));
}
System.out.printf("该表达式的结果是:%s",stack_value.getTop());
}
public static Boolean symbol(char ch) {
return ch != '+' && ch != '-' && ch != '*' && ch != '/';
}
public static int priority(String ch) {
int p = 0;
switch (ch.charAt(0)) {
case '+':
case '-': {
p = 1;
break;
}
case '*':
case '/': {
p = 2;
break;
}
}
return p;
}
public static int makeCalculate (String num2, String num1 ,char ch) {
int num = 0;
switch (ch) {
case '+':
num = Integer.parseInt(num1) + Integer.parseInt(num2);
break;
case '-':
num = Integer.parseInt(num1) - Integer.parseInt(num2);
break;
case '*':
num = Integer.parseInt(num1) * Integer.parseInt(num2);
break;
case '/':
num = Integer.parseInt(num1) / Integer.parseInt(num2);
break;
}
return num;
}
}
// 数组模拟栈
class Stack {
private int maxSize;
private int top = -1;
private String [] stack;
Stack (int maxSize) {
this.maxSize = maxSize;
this.stack = new String[maxSize];
}
// 判断栈为满
public Boolean isFull () {
return top == maxSize -1;
}
// 判断栈为空
public Boolean isEmpty () {
return top == -1;
}
// 入栈
public void push (String value) {
if (!isFull()) {
stack[++top] = value;
} else {
throw new RuntimeException("栈已满!");
}
}
// 出栈
public String pop () {
if (!isEmpty()) {
return stack[top--];
} else {
throw new RuntimeException("栈为空!");
}
}
// 获取栈顶元素
public String getTop() {
if (!isEmpty()) {
return stack[top];
} else {
throw new RuntimeException("栈为空!");
}
}
// 遍历栈
public void check () {
int index = 0;
if (!isEmpty()) {
System.out.println("从栈底到栈顶的元素依次为:");
while (index <= top){
System.out.printf("arr[%d] = %s\n",index,stack[index]);
index++;
}
} else {
throw new RuntimeException("栈中没有元素!");
}
}
}