不多说,直接上代码 注释写的还算清楚,就不再啰嗦了
package wq;
import java.util.Stack;
/**
* @author wq
* 计算类,中缀表达式转后缀表达式
*/
public class Calculator {
Stack<Integer> operatorStack=new Stack<Integer>();//符号栈
String expression ;//中缀表达式
public Calculator(String expression ) {
expression=expression.replaceAll(" ", "");//去除空格
this.expression=expression;
}
public static void main(String[] args) {
Calculator calculator=new Calculator("9 +(3-1)*3+ 10/2");
System.out.println(calculator.getSuffixExpression());
}
/**
* 获取后缀表达式
* @return
*/
String getSuffixExpression(){
char[] tmpExp=expression.toCharArray();
StringBuffer newExp=new StringBuffer();
int index=0;//从左往右依次读取字符,记录读到的位置
while(index<tmpExp.length){
if(nextIsOperator(tmpExp,index)){
int op=getOp(tmpExp,index);//读取下一个操作符
//获取栈顶符号 为空则默认使用'(' 代替,目前'('优先级最低
int popOp=operatorStack.isEmpty()?'(':operatorStack.peek();
index++;
switch(op){
case '+':
case '-':
if(op1Higher(op, popOp)){//如果遇到的操作符优先级高,直接入栈
operatorStack.push(op);
}
else {
int tmpOp=0;
//依次弹出栈内 低于当前操作符的其他操作符
while(!operatorStack.isEmpty()&&!op1Higher(op,(tmpOp=operatorStack.pop()))){
newExp.append((char)tmpOp);
System.out.print((char)tmpOp);
}
operatorStack.push(op);//入栈
}
break;
case '*':
case '/':
if(op1Higher(op, popOp)){
operatorStack.push(op);
}
break;
case '(':
operatorStack.push(op);
break;
case ')':
int tmpOp;
//依次弹出栈内 操作符 直到遇到'(' 为止
while(!operatorStack.isEmpty()&&(tmpOp=operatorStack.pop())!='('){
newExp.append((char)tmpOp);
System.out.print((char)tmpOp);
}
break;
}
}else {//数字直接输出
int num= getNum(tmpExp,index);
index=index+String.valueOf(num).length();
newExp.append(num);
System.out.print(num);
}
}
while (!operatorStack.isEmpty()) {//所有符号出栈
int op=operatorStack.pop();
newExp.append((char)op);
System.out.print((char)op);
}
System.out.println();
return newExp.toString();
}
/**
* 判断操作符op1 是否具有更高的优先级(可能有漏洞
* @param op1
* @param op2
* @return
*/
private boolean op1Higher(int op1,int op2){
if(op2=='(' ||(op1=='*'||op1=='/')){//运算符op1具有更高的优先级,表示可以直接入栈
return true;
}else if(op2!='(' && (op1=='+' || op1=='-')){
return false;
}
return false;
}
/**
* 获取下一个数字
* @param tmpExp
* @param offect
* @return
*/
private int getNum(char[] tmpExp,int offect) {
int num=0;
for (int i = offect; i < tmpExp.length; i++) {
if(Character.isDigit(tmpExp[i])){
num=num*10+tmpExp[i]-'0';//字符转数字
}else{
break;
}
}
return num;
}
/**
* 获取下一个操作符
* @param tmpExp
* @param offect
* @return
*/
private char getOp(char[] tmpExp,int offect) {
return tmpExp[offect];
}
/**
* 判断下一个字符是否为操作符
* @param tmpExp
* @param offect
* @return
*/
private boolean nextIsOperator(char[] tmpExp,int offect) {
char op=tmpExp[offect];
return (op=='+'||op=='-'||op=='*'||op=='/'||op=='('||op==')');
}
}