问题引入:
在计算机中,后缀表达式的运行效率要高于中缀表达式,而中缀表达式转后缀表达式可以通过栈来实现,那么什么是中缀表达式和后缀表达式呢?
中缀表达式
中缀表达式其实就是我们平常使用的计算的式子,比如a+b,ab,或者再稍微复杂一点的a+bc-d/e等等
后缀表达式
后缀表达式是将操作符至于操作数之后的一种式子,运算规则是遇到操作符将前面两个操作数进行相应的运算(一般情况下操作符是二目运算符,这里的也只以二目运算符为例),比如上面的中缀表达式转换成对应的后缀表达式,分别是:ab+,ab*,abc*+de/-
算法思想:
遇到运算符将运算符入栈,后面遇到的运算符如果比栈顶运算符优先级更高或相等,则入栈,反之,栈顶的运算符出栈,直至栈顶的运算符优先级高于后面遇到的运算符为止(可以将左括号与右括号也理解为运算符,但在处理时有些特殊,左括号优先级最高,右括号优先级最低,且遇到右括号要将左括号之后的运算符全部出栈),遇到非运算符直接输出
代码实现:
这里提供的是函数,可以放到一个Demo类里用main函数去测试
//中缀转后缀
public String toPostfix(String str)throws Exception{
if(str!=null&&str!=""){
LinkStack lsta=new LinkStack();
String postfix="";
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
if(c!=' '){
if(isLeftBracket(c)) lsta.push(c);
else if(isRightBracket(c)){
while(!isLeftBracket(c)){
postfix=postfix.concat(lsta.pop()+"");
//使用pop方法,因为要将左括号出栈
c=(Character)lsta.pop();
}
}else if(isOperator(c)){
while(!lsta.isEmpty()&&prior(c)<=prior((Character)lsta.peek())){
postfix=postfix.concat(lsta.pop()+"");
}
lsta.push(c);
}else postfix=postfix.concat(c+"");
}
}
while(!lsta.isEmpty()) postfix=postfix.concat(lsta.pop()+"");
return postfix;
}
throw new Exception("中缀表达式不能为空!!");
}
//判断是否是运算符
public boolean isOperator(char c) {
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') return true;
return false;
}
//判断左括号
public boolean isLeftBracket(char c){
return c=='(';
}
//判断右括号
public boolean isRightBracket(char c){
return c==')';
}
//求运算符的优先级
public int prior(char c){
if(c=='+'||c=='-') return 1;
else if(c=='*'||c=='/'||c=='%') return 2;
else if(c=='^') return 3;
else return 0;
}
//计算后缀表达式
public double runPostfix(String postfix) throws Exception{
LinkStack lsta=new LinkStack();
Double res=0.0;
for(int i=0;i<postfix.length();i++) {
char c=postfix.charAt(i);
if(isOperator(c)) {
try {
Double num2=Double.parseDouble(lsta.pop()+"");
Double num1=Double.parseDouble(lsta.pop()+"");
if(c=='+') {
res=num1+num2;
}else if(c=='-') {
res=num1-num2;
}else if(c=='*') {
res=num1*num2;
}else if(c=='/') {
res=num1/num2;
}else if(c=='%') {
res=num1%num2;
}else if(c=='^') {
res=Math.pow(num1, num2);
}
lsta.push(res);
}catch(Exception ex) {
throw new Exception("后缀表达式不合法!!");
}
}
else lsta.push(c);
}
res=Double.parseDouble(lsta.pop()+"");
return res;
}
如有任何错误的地方,望各位大佬批评指正