这是刚学数据结构时候碰到的题了,当时还觉得有点难,现在又碰到了这道题,理清思路后还是把它编出来了,编程过程中真是处处是陷阱,踩完一个又一个,果然还是练得太少了。这道题核心思想是将中缀表达式转换为后缀表达式。我用了两个栈来实现这个操作。解析输入的字符串,如果是数字则入数字栈,是操作符则比较当前操作符和操作符栈顶操作符的优先级,若当前操作符优先级较高,则从数字栈中弹出两个数进行运算,否则将当前操作符压入栈中,其中‘)’不入栈并弹出‘(’。
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String args[]){
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
int result=getResult(s);
System.out.println(result);
scanner.close();
}
public static boolean compare(char p, char c) {// 如果是p优先级高于c,返回true,默认都是p优先级要低
if (p == '*'
&& (c == '+' || c == '-' || c == '/' || c == '*'||c=='(')) {// 如果c是'(',那么c的优先级高,如果是')',是在上面处理
return true;
} else if (p == '/'
&& (c == '+' || c == '-' || c == '*' || c == '/'||c=='(')) {
return true;
} else if (p == '+' && (c == '+' || c == '-'||c=='(')) {
return true;
} else if (p == '-' && (c == '+' || c == '-'||c=='(')) {
return true;
} else if (c == '#') {// 这个很特别,这里说明到了中缀表达式的结尾,那么就要弹出操作符栈中的所有操作符到后缀表达式中
return true;// 当c为'#'时,c的优先级算是最低的
}
return false;// 开括号是不用考虑的,它的优先级一定是最小的,c一定是入栈
}
public static int calculate(int a,int b,char c){
int result=0;
switch(c){
case '+':
result=a+b;
break;
case '-':
result=a-b;
break;
case '*':
result=a*b;
break;
case '/':
result=a/b;
break;
}
return result;
}
public static int getResult(String inputString){
inputString=inputString+'#'+"";
int length=inputString.length();
Stack<Integer> data=new Stack<Integer>();
Stack<Character> character=new Stack<Character>();
character.push('#');
StringBuffer buffer;
int i=0;
while(i<length){
buffer=new StringBuffer("");
char temp;
temp=inputString.charAt(i);
if('0'<=temp&&temp<='9'){ //是数字
while('0'<=temp&&temp<='9'&&i<length){
buffer=buffer.append(temp+"");
i++;
if(i<length){
temp=inputString.charAt(i);
}
}
data.push(Integer.parseInt(buffer.toString()));
}else{ //是操作符
switch(temp){
case '(':
character.push(temp);
break;
case ')':
char c=character.peek();
int r=0;
while(c!='('){ //循环读取直至匹配左括号
int b=data.pop();
int a=data.pop();
r=calculate(a,b,c);
data.push(r);
character.pop(); //弹出操作符
c=character.peek();
}
character.pop(); //弹出左括号
break;
default:
char c1=character.peek();
if(!compare(temp,c1)){ //当前操作符比栈顶操作符优先级低
while(!compare(temp,c1)){ //运算直至操作符比栈顶操作符优先级高
character.pop();
int b1=data.pop();
int a1=data.pop();
int r1=0;
r1=calculate(a1,b1,c1);
data.push(r1);
c1=character.peek();
}
character.push(temp);
}else{ //当前操作符比栈顶操作符优先级高
character.push(temp);
}
break;
}
i++;
}
}
return data.pop();
}
}