先扯个蛋@.@
后缀表达式,作用在于方便计算机来计算表达式的一种表达式。=。=好啰嗦。
直接举一个例子吧:
比如ab*cd+/:
从左到右扫描,扫描到一个运算符,就将前面两个数字来做运算
ab*—->变成a*b,作为一个整体的值。然后继续扫描到+号,就把cd加起来成为一个整体的值c+d,然后继续扫描到/号,就把前面计算的两个值相除,即(a*b)/(c+d)。这个表达式是我们容易读的,叫做中缀表达式。为了能够让计算机能很好的计算,我们要把它变成后缀表达式。
然后不罗嗦,直接上代码
public class nifix2postfix {
public static Map<Character, Integer> privMap;
public static StringBuffer postFixBuffer = new StringBuffer();
public static void findPostFix(String nifix){
//初始化运算符的优先级
privMap = new HashMap<Character, Integer>();
privMap.put('*', 2);
privMap.put('/', 2);
privMap.put('+', 1);
privMap.put('-', 1);
//后缀表达式结果
//操作符栈
Stack<Character> operatorsStack = new Stack<Character>();
//从第一位读取
for(int i=0;i<nifix.length();++i){
char read = nifix.charAt(i);
System.out.println("读取的字符是:"+read);
//如果是数字,就直接放入postFixBuffer中(这里的数字用小写字母来表示)
if(read>='a'&&read<='z'){
postFixBuffer.append(read);
continue;
}
//如果是操作符
else if(privMap.containsKey(read)){
if(operatorsStack.size()!=0){
int stackSize = operatorsStack.size();
for(int m = 0;m<stackSize;++m){
char c = operatorsStack.peek();
//1.如果比栈顶的优先级要高,就直接放到栈中,或者弹没了
if(privMap.get(c)<=privMap.get(read)||operatorsStack.size()==0)
{
System.out.println(read+" 优先级比栈顶的"+c+"优先级高,所以放入栈中");
operatorsStack.push(read);
break;
}
//2.如果比栈顶的要低,就把在栈中比它优先级高的都放到结果中后,再压入栈中
else{
System.out.println("将优先级大的:"+c+" 弹出");
postFixBuffer.append(operatorsStack.pop());
if(operatorsStack.size()==0)
operatorsStack.push(read);
}
}
}
else{
System.out.println("由于栈内没有元素,所以直接压入:"+read);
operatorsStack.push(read);
}
}
else if(read=='('){
int range = i;
Stack<Character> match = new Stack<Character>();
match.push(nifix.charAt(i));
for(int temp=i+1;temp<=nifix.length();++temp){
if(match.isEmpty()){
range = temp;
break;
}
if(nifix.charAt(temp)==')'){
match.pop();
}
else if(nifix.charAt(temp)=='(')
match.push('(');
}
//递归找到括号内的后缀表达式
System.out.println("递归做:"+nifix.substring(i+1, range-1));
findPostFix(nifix.substring(i+1, range-1));
i = range+1;
}
}
while(operatorsStack.size()!=0){
postFixBuffer.append(operatorsStack.pop());
}
System.out.println(postFixBuffer);
// return postFixBuffer.toString();
};
}
算法解释
首先要定义一个privMap,一个HashMap,用于储存某个运算符的优先级的。接下来,扫描的过程是:
1.从左到右扫描表达式
2.如果遇到数字,直接加入后缀表达式
3.如果遇到操作符,如果其优先级比栈内元素都高,就放入栈中。相反,把栈内优先级比该操作符高的都pop到后缀表达式中
4.遇到括号的话常用递归,找到括号内的表达式,然后传给同一个函数处理