实现原理
-
创建两个栈,分别为操作符栈和操作数栈,操作符栈存放“+”,“-”,“*”,“/”运算符,操作数栈存放需要进行操作的数。
-
通过输入一个前缀表达式,通过inserblanks将表达式格式化。再调用split函数分割表达式。
-
将分割后的表达式,用for循环遍历,当遇到长度为0的字符串时,直接跳过本次循环。其他符号操作如下:
-
当 “+” 和 “-” 入栈时判断栈内是否有其他运算符,如果有的话,则将栈内运算符处理过后再入栈。
-
当 “*” 和 “/” 入栈时,判断操作符栈内是否存在 “ * ” 和 " / " ,如果有的话,则先处理栈内的操作符后再入栈。
-
当输入括号时,如果此时栈内为空,则直接入栈,如果此时栈内有匹配括号,则将匹配域内的符号一起处理,然后将括号弹栈。
-
具体原理图如下:
其中:格式化处理表达式的代码为:
//输入一个表达式字符串,遍历字符串,在(,),+,,-,*,/前后加上一个空格,便于调用字符串切割函数
private static StringBuffer insertBlanks(String str) {
StringBuffer str2 = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
if (!str2.toString().endsWith(" ")) {
str2.append(" ");
}
str2.append(str.charAt(i));
str2.append(" ");
} else {
str2.append(str.charAt(i));
}
}
return str2;
}
处理了前缀表达式后,调用String类的split函数切割函数切割字符串,然后再将字符串入栈进行操作,具体代码如下:
import java.util.Scanner;
public class ArrayStackTest4 {
public static void main(String[] args) {
ArrayStack<String> arrayStack = new ArrayStack<>();
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
StringBuffer str3 = insertBlanks(str);//格式化字符串
String[] arrStr = str3.toString().split(" ");
ArrayStack<String> stringArrayStack = new ArrayStack<>();
ArrayStack<Float> integerArrayStack = new ArrayStack<>();
for(String st:arrStr){
//处理空格情况,直接跳过
if(st.length()==0){
continue;
}
if(stringArrayStack.isEmpty()&&(st.equals("+")||
st.equals("-")||
st.equals("*")||
st.equals("/"))){
stringArrayStack.push(st);
continue;
}
//当操作栈入栈+或者-的时候,之前的操作全部出栈。
if(st.equals("+")||st.equals("-")){
while(!stringArrayStack.isEmpty()&&(
stringArrayStack.peek().equals("+")||
stringArrayStack.peek().equals("-")||
stringArrayStack.peek().equals("*")||
stringArrayStack.peek().equals("/"))){
processAnOperater(integerArrayStack,stringArrayStack);
}
stringArrayStack.push(st);
//当操作栈入栈*或者/的时候,操作栈中的*或者/出栈
}else if(st.equals("*")||st.equals("/")){
while(!stringArrayStack.isEmpty()&&(stringArrayStack.peek().equals("*")||
stringArrayStack.peek().equals("/"))){
processAnOperater(integerArrayStack,stringArrayStack);
}
stringArrayStack.push(st);
//当加入左括号造的时候,直接入栈
}else if(st.equals("(")){
stringArrayStack.push("(");
//当加入右括号的时候,清空栈内的一切操作,并将左括号弹栈。
}else if(st.equals(")")){
while(!stringArrayStack.peek().equals("(")){
processAnOperater(integerArrayStack,stringArrayStack);
}
stringArrayStack.pop();
}else {
integerArrayStack.push(Float.parseFloat(st));//将字符串中的数字转化为Int类型放入数字栈
}
}
if(!stringArrayStack.isEmpty()){
processAnOperater(integerArrayStack,stringArrayStack);
}
System.out.println(integerArrayStack.pop());
}
private static void processAnOperater(ArrayStack<Float> integerArrayStack, ArrayStack<String> stringArrayStack) {
float num1=integerArrayStack.pop();
float num2=integerArrayStack.pop();
if(stringArrayStack.peek().equals("+")){
integerArrayStack.push(num2+num1);
}
if(stringArrayStack.peek().equals("-")){
integerArrayStack.push(num2-num1);
}
if(stringArrayStack.peek().equals("*")){
integerArrayStack.push(num1*num2);
}
if(stringArrayStack.peek().equals("/")){
integerArrayStack.push(num2/num1);
}
stringArrayStack.pop();
}
private static StringBuffer insertBlanks(String str) {
StringBuffer str2 = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
if (!str2.toString().endsWith(" ")) {
str2.append(" ");
}
str2.append(str.charAt(i));
str2.append(" ");
} else {
str2.append(str.charAt(i));
}
}
return str2;
}
}