前面一節寫了實現計算器的兩位數的運算功能,本章簡單闡述可以進行多個數的四則運算的計算器。
首先展示執行效果:
通過棧的思想來實現多個數的判斷以及運算。
依照棧後進先出的原則,可以依次根據運算子的優先順序進行數的運算。
我們通常輸入的一串數為中綴表示式,如: 1+2*3,
人當然可以容易識別先運算哪個,後運算哪個,但機器沒有人的思維,如果你不幫它把順序排好,它可就瞎幾把幫你運算了,說人話就是機器無法判斷運算子優先順序,所以只會從左到右一步一步的運算。
既然機器只能從左到右運算,那就只有人來幫它排好順序,讓笨拙的機械人慢慢算它的吧。
所以產生了字尾表示式,上面的表示式則可以轉化為: 1 2 3 * +
機器從左到右遍歷數字壓入數字棧,當遍歷到字元時,將數字棧頂的數彈出,然後進行運算,再將結果壓入數字棧頂,到下次又掃瞄到運算子時,再重複前面的步驟,直到數字棧只有乙個數時,返回結果。
相信大家都有了基本的想法了,然後就是具體實現了,這裡主要將演算法的實現步驟,這個才是重點。
前面差不多都是廢話,可以不用看,但是下面的步驟還是請看下,思路簡單,但實現不易
中綴表示式轉為字尾表示式的過程
從左到後遍歷中綴表示式,如果是數字則將數字儲存到乙個臨時變數中。
掃瞄到運算子後,再將前面的數新增到字尾表示式中,這樣做的目的是便於區分有沒有大於10以上的數和有小數點的數(到後面將數壓棧就懂了,為啥這樣做),同時將運算子壓入運算子棧中。
然後再遍歷,重複第乙個過程,當再次遇到運算子時,再將數字新增到字尾表示式,然後將改運算子與壓入棧頂的運算子比較優先順序,如果該運算子優先順序比棧頂元素優先順序更高,則直接將該運算子新增到字尾表示式後面。
重複以上步驟,直到將整個字串傳到字尾表示式中。
主要**:
private boolean isinstack = false;//是否檢測到運算子
private boolean calculateone = true; //刪除棧頂的『#』
/* private boolean judgeonfirst = true; */
stackst = new stack(); //運算元棧,初始化
/* *中綴表示式 1+2*10-2
*字尾表示式 1
210 * + 2 - # 中間以空格來分割每個數和運算子
public string converpostfix(string expression) throws exception
if (!st.isempty()&& c!='#')
if(ac!=null)
}st.push(c);//運算子入棧
}else }}
while (!st.isempty())
postfix +=" "+st.pop().tostring(); //如果棧非空,需要將棧中所有運算子串聯到字尾表示式的末尾
}return postfix; //返回字尾表示式
}
/**
* 得到字尾表示式
* 1 2 10 * + 2 - #
* new乙個數字棧存放數
* 遍歷
* 如果遇到數,就先將其存放在乙個臨時的位置中
* 如果遇到空格便將前面遍歷到的數壓入棧中push(),同時將臨時存放的資料更新
* 因為同時會將空格壓入棧中,所以新增乙個判斷有沒有空格,當空格壓入棧中後,立即將空格退出棧
* 如現在棧中得到的數就是
* i=0 "1"
* i=1 "2"
* i=2 "10"
* 遇到*號,依照棧後進先出的原則,
* d2 =10.0 d1= 2.0 result = 10.0*2.0 然後將結果壓入棧
* i=0 "1"
* i=1 "20"
* 遇到+號
* d2=20.0 d1 =1.0 result =20.0+1.0 結果壓入棧
* 同理
*@param postfix
*@return
*@throws exception
*/public string numbercalculate(string postfix) throws exception
}if (isoperator(c))
result=d1/d2;
break;
default:
break;
}string value =string.valueof(result);
if (value.indexof(".")>0)
st.push(value); //操作後的結果入棧
}else
}return st.pop();
}
/**
* 優先順序
*@param c
*@return
*/private
intpriority(char c)
return
0; }
/*** 判斷是否是乙個操作符
*@param c
*@return
*/private
boolean
isoperator(char c)
return
false;
}
多個數運算主要問題就是:
如何識別數只有一位或是多位? 如 : 1 10 10.5
因為存在乙個壓棧問題,只能將乙個完整的數壓入棧,如果不能判斷10是乙個完整的數,壓入棧時就只能先壓入1 再壓入0
判斷運算子優先順序的問題?
但以上分析還不夠完善,歡迎指正!
附上完整demo示例:
Android Studio主題設定
android studio發布也好多天了。剛好本人目前的專案需要android平板和pc區域網連線操作。就開始使用android studio了。不過預設的介面實在看不過眼,下面我們來看看android studio的主題吧。我們先選擇nimbus試試,這個名字很熟悉吧!整個介面煥然一新了吧。當然...
Android Studio編碼問題
不同於eclipse,選中專案右擊即會出現 properties 選項,可以設定專案檔案的預設編碼,可以根據自己的需要設定為utf 8 gb2312等編碼。但android studio的專案設定邏輯與eclipse有很大的區別,執行的操作為file setting file encodings然後...
Android Studio 入門指南
作為乙個android 開發者,你應該很了解android studio,如果你現在還不了解,沒關係,那麼從現在開始,我們一起來了解了解andoid studio。android studio 是google 官方在2013 google i o 大會 2013 年5月 上發布的全新andrid 開...