牛客題目:請寫乙個整數計算器,支援加減乘三種運算和括號。
題目給出的算術表示式主要包括三部分:運算元、括號、運算子
一般的算術表示式都是中綴表示式,不易於程式設計計算。所以我們可以利用逆波蘭演算法將算術表示式的中綴形式轉為更易於計算的字尾形式。
轉換為字尾表示式的過程需要借助兩個額外空間,棧s和陣列列表l,其中棧用於儲存左括號和運算子,陣列列表用於儲存字尾表示式。
整個步驟是:
遍歷算術表示式:
1、如果遇到了運算元,那麼此時需要考慮乙個問題:那就是當前這個運算元是單位數還是多位數的一部分,如果是單位數,那麼直接加入到陣列列表l中;如果是多位數,那麼需要利用while迴圈,將這個多位數連線起來,形成乙個整體,然後放入陣列列表
2、如果遇到了分界符,即括號,那麼判斷它如果是左括號「(」,則直接入棧;如果是右括號「)」,則說明已有一對括號配對,那麼直接丟棄這個右括號,然後對棧進行出棧操作,將出棧的元素加入到l中,然後一直迴圈出棧,直到遇到左括號,則出棧結束,並將出棧的左括號丟棄。
3、如果遇到了運算子op1,此時觀察棧頂元素op2
(1)如果棧為空,則直接將op1入棧;
(2)如果op2不是運算子,則直接將op1入棧;
(3)如果op2是運算子,則比較op1和op2的優先順序:如果op1優先順序大於op2,則直接將op1入棧;否則,將op2出棧,並加入到l中,然後如果新的棧頂依舊是運算子的話,則繼續進行優先順序的判斷;
其中,第(2)(3)步驟可以通過乙個while迴圈解決,while迴圈的條件是:棧非空&&棧頂元素是運算子&&棧頂元素優先順序大於op1的優先順序,這樣做的目的是保證如果棧中有連續相鄰的運算子,則上邊的運算子的優先順序要大於下邊的運算子的優先順序。
4、最後,如果棧中還有元素的話,則全部追加到陣列列表中。
以上步驟就是中綴表示式轉為字尾表示式的過程,然後就是利用得到的字尾表示式計算結果了,具體過程是:
1、仍需借助乙個棧,用於儲存運算元和中間結果
2、對字尾表示式進行遍歷
(1)如果遇到的是運算元,則進棧;
(2)如果遇到了運算子,則連續出棧兩個元素,其中先出棧的是運算子右邊的元素,後出棧的是運算子左邊的元素,然後按照運算子對兩個數進行計算,得出的中間結果再次放入棧中,
3、遍歷完成之後,棧頂元素就是最終的計算結果。
private hashmappri = new hashmap<>();
public int solve (string s)
pri.put('+',0);
pri.put('-',0);
pri.put('*',1);
listsuffixs = getsuffix(s);
system.out.println(suffixs);
stackstack = new stack<>();
int res = 0;
for (string suffix : suffixs)
}else
}return stack.pop();
}private listgetsuffix(string s)else if (curchar == ')')
list.add(ch.tostring());
}// 2、運算子
}else if (curchar == '+' || curchar == '-' || curchar =='*')else
stack.push(curchar);
}// 3、運算元
}else
list.add(cur.tostring());
}if (old_i == i)
}while (!stack.isempty())
return list;
}
算術表示式求解背景 逆波蘭表示式
逆波蘭表示式是一種把運算子前置的算術表示式,例如普通的表示式2 3的逆波蘭表示法為 2 3。逆波蘭表示式的優點是運算子之間不必有優先順序關係,也不必用括號改變運算次序,例如 2 3 4的逆波蘭表示法為 2 3 4。本題求解逆波蘭表示式的值,其中運算子包括 四個。輸入 輸入為一行,其中運算子和運算數之...
逆波蘭算術表示式
傳統的算術表示式是由運算元 又叫運算物件或運算量 和運算子以及改變運算次序的圓括號連線而成的式子。其運算規則如下 1 先計算括號內,後計算括號外 2 在無括號或同層括號內,先進行乘除運算,後進行加減運算,即乘除運算的優先順序高於加減運算的優先順序 3 同一優先順序運算,從左向右依次進行。在這種表示式...
波蘭表示式 逆波蘭表示式
中綴表示式是最常見的運算表示式,如 3 5 2 6 1 波蘭表示式又稱為字首表示式,它是由中綴表示式經過一定的方式轉換來的 比如中綴表示式為 3 5x 2 6 1 對應的字首表示式為 3 x 5 2 6 1 對於中綴表示式從右向左遍歷轉換為字首表示式,中途要是用棧進行儲存 轉換規則如下 波蘭表示式 ...