題目
利用計算機計算算數表達式,只包含加減乘除四則運算,比如:34+13*9+44- 12/3
思路:通過兩個棧來實現的。其中一個保存操作數的棧,另一個是保存運算符的棧。我們從左向右遍歷表達式,當遇到數字,我們就直接壓入操作數棧;當遇到運算符, 就與運算符棧的棧頂元素進行比較。如果比運算符棧頂元素的優先級高,就將當前運算符壓入棧;如果比運算符棧頂元素的優先 級低或者相同,從運算符棧中取棧頂運算符,從操作數棧的棧頂取 2 個操作數,然後進行 計算,再把計算完的結果壓入操作數棧,繼續比較。
public class StackTest {
private int calcuteResult(int a,int b,char sym){
int result = 0;
switch (sym){
case '+':result = a + b;break;
case '-':result = a - b;break;
case '*':result = a * b;break;
case '/':result = a / b;break;
default:break;
}
return result;
}
/**
* 利用計算機計算算數表達式,只包含加減乘除四則運算,比如:34+13*9+44- 12/3
*
* 思路:通過兩個棧來實現的。其中一個保存操作數的棧,另一個是保存運算符的棧。
* 我們從左向右遍歷表達式,當遇到數字,我們就直接壓入操作數棧;當遇到運算符,
* 就與運算符棧的棧頂元素進行比較。如果比運算符棧頂元素的優先級高,就將當前運算符壓入棧;
* 如果比運算符棧頂元素的優先 級低或者相同,從運算符棧中取棧頂運算符,從操作數棧的棧頂取 2 個操作數,
* 然後進行 計算,再把計算完的結果壓入操作數棧,繼續比較。
*/
@Test
public void test1(){
Stack<Integer> data = new Stack<>();
Stack<Character> symbol = new Stack<>();
//String str = "34+13*9+44-12/3";
String str = "34+13*9+44-12/3*1";
int result = 0;//= calcuteResult(2,4,'*');
int dd = 0;
for(int i=0;i<str.length();i++){
if(str.charAt(i)>=48&&str.charAt(i)<=57){
//如果爲數字,則利用 dd 中間變量計算值
dd = dd * 10 + str.charAt(i) - 48;
//表達式最後一位爲數字,壓入堆棧
if(i == str.length() -1){
data.push(dd);
dd = 0;
}
}else {
//如果爲運算符,則將中間變量dd壓入堆棧
data.push(dd);
dd = 0;
//如果運算符棧爲空,則將運算符直接壓入堆棧
if(symbol.size() == 0) {
symbol.push(str.charAt(i));
}else if((str.charAt(i) == '+' || str.charAt(i) == '-')
&&(symbol.peek() == '*' || symbol.peek() == '/')){
//如果當前的運算符 str.charAt(i) 優先級小於 symbol 棧頂,則取出
// 數據棧 data 的前兩個數值,與棧頂運算符一起計算,並將計算結果壓入數據棧
int b = data.pop();
int a = data.pop();
result = calcuteResult(a,b,symbol.pop());
data.push(result);
symbol.push(str.charAt(i));
}else {
//棧頂不爲空,且當前的運算符的優先級也不小於棧頂運算符,則將當前運算符壓入堆棧
symbol.push(str.charAt(i));
}
}
}
//對數據棧與運算符棧中剩餘元素進行計算
while (symbol.size() > 0){
int b = data.pop();
int a = data.pop();
char sys = symbol.pop();
result = calcuteResult(a,b,sys);
data.push(result);
}
System.out.println("計算結果:"+result);
}
}
輸出結果:
計算結果:191