将一个普通的中序表达式转换为逆波兰表达式的一般算法是:
(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将栈顶的运算符从栈中弹出,直到栈顶运算符的优先级低于当前运算符,将该字符入栈。
(5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
import java.util.HashMap; import java.util.Map; import java.util.Stack; public class Main { private final static Map<Character, Integer> SYMBO_LEVEL = new HashMap<Character, Integer>(); static { SYMBO_LEVEL.put('#', 0); SYMBO_LEVEL.put('^', 7); SYMBO_LEVEL.put('*', 5); SYMBO_LEVEL.put('/', 5); SYMBO_LEVEL.put('%', 5); SYMBO_LEVEL.put('+', 3); SYMBO_LEVEL.put('-', 3); SYMBO_LEVEL.put('(', 1); SYMBO_LEVEL.put(')', 8); } private Stack<Character> symboStack = new Stack<Character>(); private Stack<Character> valueStack = new Stack<Character>(); public void clearStack() { symboStack.clear(); symboStack.add('#'); valueStack.clear(); } public boolean isSymbo(Character c) { return SYMBO_LEVEL.containsKey(c); } public void getRPE(String expression) { clearStack(); for (int i = 0; i < expression.length(); i++) { Character c = expression.charAt(i); if (isSymbo(c)) { // 运算符 if (c.equals('(')) { symboStack.push(c); } else if (c.equals(')')) { Character tempC = symboStack.pop(); while (!tempC.equals('(')) { valueStack.push(tempC); tempC = symboStack.pop(); } } else { Character tempC = symboStack.peek(); int level = SYMBO_LEVEL.get(c); int tempLevel = SYMBO_LEVEL.get(tempC); while (tempLevel >= level) { valueStack.push(symboStack.pop()); // out tempLevel = SYMBO_LEVEL.get(symboStack.peek()); } symboStack.push(c); } } else { valueStack.push(c); } } // 将剩余的符号位加入到逆波兰式中 int length = symboStack.size() - 1; for (int i = 0; i < length; i++) { valueStack.push(symboStack.pop()); } System.out.println(valueStack); } public int counter(String expression) { getRPE(expression); Stack<Integer> result = new Stack<Integer>(); Stack<Character> tempResult = new Stack<Character>(); tempResult.push('#'); int size = valueStack.size(); for (int i = 0; i < size; i++) { tempResult.add(valueStack.pop()); } Character c = tempResult.pop(); while (c != '#') { if (isNum(c)) { result.push(Integer.valueOf(c + "")); } else { int right = result.pop(); int left = result.pop(); if (c.equals('+')) { result.push(left + right); } else if (c.equals('-')) { result.push(left - right); } else if (c.equals('*')) { result.push(left * right); } else { result.push(left / right); } } c = tempResult.pop(); } return result.pop(); } private boolean isNum(Character c) { return c >= '0' && c <= '9'; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Main m = new Main(); System.out.println(m.counter("5+2*(5*3+4*3-1)")); // m.getRPE("5+2"); } }
结果为:
[5, 2, 5, 3, *, 4, 3, *, +, 1, -, *, +]
57
1549

被折叠的 条评论
为什么被折叠?



