問題描述:
給定四則運算字符串,輸出運算結果
輸入描述:
1/2*(3+(4-5))
輸出描述:
1.0
1> 問題分析
使用棧將中綴表達式轉換爲後綴表達式,計算後綴表達式;
☞ 前綴:prefix
☞ 中綴:infix
☞ 後綴:postfix
2> 實現
- 中綴表達式轉後綴表達式
/*
* 中綴轉後綴
*/
public static LinkedList<Character> convertToPostfix(String infix) {
LinkedList<Character> valueStack = new LinkedList<Character>();
LinkedList<Character> operatorStack = new LinkedList<Character>();
HashMap<Character, Integer> baseOperatorMap = new HashMap<Character, Integer>();
baseOperatorMap.put('(', 0);
baseOperatorMap.put('+', 1);
baseOperatorMap.put('-', 2);
baseOperatorMap.put('*', 3);
baseOperatorMap.put('/', 4);
Character topOperator = null;
while (!infix.isEmpty()) {
int index = 0;
char nextCharacter = infix.charAt(index);
//System.out.println(nextCharacter + " " + valueStack + " " + operatorStack);
if (Character.isDigit(nextCharacter)) {
valueStack.push(nextCharacter);
} else if (nextCharacter == '+' || nextCharacter == '-' || nextCharacter == '*' || nextCharacter == '/') {
if (!operatorStack.isEmpty()) {
if (baseOperatorMap.get(nextCharacter) <= baseOperatorMap.get(operatorStack.getFirst())) {
topOperator = operatorStack.pop();
operatorStack.push(nextCharacter);
valueStack.push(topOperator);
} else {
operatorStack.push(nextCharacter);
}
}else{
operatorStack.push(nextCharacter);
}
} else if (nextCharacter == '(') {
operatorStack.push(nextCharacter);
} else if (nextCharacter == ')') {
topOperator = operatorStack.pop();
while (topOperator != '(') {
valueStack.push(topOperator);
topOperator = operatorStack.pop();
}
} else if (nextCharacter == ' ') {
} else {
System.out.println("格式有誤!");
return null;
}
index++;
infix = infix.substring(index);
}
//operatorStack非空
while(!operatorStack.isEmpty()){
topOperator = operatorStack.pop();
valueStack.push(topOperator);
}
return valueStack;
}
☞ 結果:[*, +, -, 5, 4, 3, /, 2, 1]
- 計算後綴表達式
☞ 由於上述棧頂到棧底的順序是後綴表達式的逆序,所以取值計算時要從最後開始取值。
/*
* 求解後綴表達式
*/
public static double calculate(String infix) {
String result = null;
double firstNum = 0;
double secondNum = 0;
LinkedList<Character> postFix = convertToPostfix(infix);
LinkedList<String> valueStack = new LinkedList<String>();
while(!postFix.isEmpty()){
//由於後綴棧爲反後綴表達式,從末尾進行彈出
Character nextCharacter = postFix.pollLast();
if(Character.isDigit(nextCharacter)){
valueStack.push(nextCharacter.toString());
}else if(nextCharacter == '+' || nextCharacter == '-' || nextCharacter == '*' || nextCharacter == '/'){
switch(nextCharacter.toString()){
case("+"):
secondNum = Double.valueOf(valueStack.pop());
firstNum = Double.valueOf(valueStack.pop());
result = Double.valueOf((firstNum+secondNum)).toString();
break;
case("-"):
secondNum = Double.valueOf(valueStack.pop());
firstNum = Double.valueOf(valueStack.pop());
result = Double.valueOf((firstNum-secondNum)).toString();
break;
case("*"):
secondNum = Double.valueOf(valueStack.pop());
firstNum = Double.valueOf(valueStack.pop());
result = Double.valueOf((firstNum*secondNum)).toString();
break;
case("/"):
secondNum = Double.valueOf(valueStack.pop());
firstNum = Double.valueOf(valueStack.pop());
result = Double.valueOf((firstNum/secondNum)).toString();
break;
}
valueStack.push(result);
}
}
return Double.valueOf(valueStack.peek());
}
- main測試
public static void main(String[] args) {
String x = "1/2*(3+(4-5))";
double result = calculate(x);
System.out.println(result);
}