程序設計第四次作業——計算器第二步(計算)
Github 鏈接:https://github.com/luojingzhao/object-oriented/tree/master/calculate
本次作業要求
<1>使用調用的方式。也就是在命令行里(如windows下的cmd)輸入表達式,得到結果。
<2>對四則運算表達式進行拆解。
<3>通過兩個棧來處理計算和優先級。
開始
從看到題目就是一臉懵逼,后來看了同學的博客和在網上相關的資料的查找,才漸漸了解的題目的大概意思,和主要的如何實現目的的代碼操作。
想法:
<1>將隊列傳入處理的函數calculate,掃描並划分哪一些是操作符,哪些是計算數;
<2>通過優先級,來處理操作符push進棧的先后;
具體實現
<1>創建兩個棧,分別用來存儲操作符和數字
stack<string> StaOper; //只處理+ - # / ()運算
stack<double> StaNum; //只處理輸入數字運算
<2>判斷是否是操作數還是數字
bool Operation::Isoperator(string str)
{
if(str == "+" || str == "-" ||
str == "*" || str == "/" ||
str == "(" || str == ")" || str == "#")
return true;
else
return false;
}
<3>主要的難點是操作符優先級的判斷,這個我想了很久也不會,於是查找了網上相關的資料
了解到計算機是無法自己識別括號,並像人工那樣計算的,只能將中綴表達式轉變為后綴表達式,以棧的方式進行讀取計算。
Operation::Operation() //定義構造函數為數據賦值
{
OprRelation[0] = ">><<<>>"; // '+'
OprRelation[1] = ">><<<>>"; // '-'
OprRelation[2] = ">>>><>>"; // '*'
OprRelation[3] = ">>>><>>"; // '/'
OprRelation[4] = "<<<<<= "; // '('
OprRelation[5] = ">>>> >>"; // ')'
OprRelation[6] = "<<<<< ="; // '#'
}
雖然借鑒了,但是主要的意思,就是這個優先級的判斷是如何得來的,還是搞不太清楚
<4>棧的存儲都完成后,最后只要取出一個操作符和兩個數字進行計算就可以了。
遇到的困難
<1>在傳入的隊列多了一個回車(這個bug讓我找了很久,一直是帶有括號的計算不了,加了很多的輸出流來檢查)
if (count<=10&&str!="") //這個位置開始我並沒有查找是否為空,就將剩余的字符push進去,導致錯誤
{
data.push(str); /*處理若末尾是未超過的數的輸出*/
str.clear();
}
<2>傳入函數的參數為指針沒有加上&
<3>在處理負數的計算要先在數字的棧push進一個‘0’
<4>完成配對用“##”的配對完成
<5>無法完成小數計算,我將輸入改為double類型
附上cmd運行的結果
不足之處
<1>對輸入的表達式是否合法,沒有進行首要的判斷
<2>在處理除數為0的情況,會出現奇怪的答案
<3>沒有用cmd傳入的形參(后來才改正的)