今天其實想要回歸單純的程式設計思考。
之前被人問過簡單的計算機要怎麼設計。
首先想到的就是計算流程是怎麼樣的
第一項其實很直覺的就是建立一個變數儲存計算後的值,遇到運算子時記錄,等待下一個運算元輸入後進行計算。
舉例來說 :
就是直接看要處理的是運算子還是運算元進行處理,所以就不多說了。
第二項由於是包含整個完整的語意流程,我們需要判斷的事情就比較多了。像是
當我們遇到有一串字串要計算,像是"10+0.5X2-7+15/3",可以透過自訂函式直接將字串轉成運算結果。
概念是透過解析字串將數字與運算符號分開,再作運算。
當找到乘除等優先權高的運算子,去找出對應的數字並且取出作完運算後存回列表,繼續流程直到沒有運算子,或是只剩下一個運算元。
例 : "10+0.5X2-7+15/3"
數字列表 : 10,0.5,2,7,15,3
運算子列表 : +,x,-,+,/
第一步
數字列表 : 10,1,7,15,3
運算子列表 : +,-,+,/
第二步
數字列表 : 10,1,7,5
運算子列表 : +,-,+
第三步
數字列表 : 11,7,5
運算子列表 : -,+
第四步
數字列表 : 4,5
運算子列表 : +
第五步
數字列表 : 9
運算子列表 :
達到條件 :沒有運算子,或是只剩下一個運算元,回傳9
先上程式碼
fun eval(strins:String) :Float{
var changeString=strins
var logiclist= arrayListOf<String>()
var numberlist =arrayListOf<Float>()
var appendString=""
for(i in 0 until changeString.length){
if(!changeString[i].isDigit() && changeString[i]!='.') {
logiclist.add(changeString[i].toString() )
numberlist.add(appendString.toFloat())
appendString=""
}
else if(i<changeString.length-1){
appendString+=changeString[i]
}
else{
appendString+=changeString[i]
numberlist.add(appendString.toFloat())
}
}
while(logiclist.size>0 && numberlist.size>1){
//先乘除
var countFirstIndex=logiclist.indexOfFirst { it ->it=="*" || it=="/" }
var countingA :Float
var countingB :Float
if(countFirstIndex>=0){
countingA=numberlist[countFirstIndex]
countingB=numberlist[countFirstIndex+1]
var temp:Float= 0F
when(logiclist[countFirstIndex]){
"*"->{
temp=countingA*1F * countingB*1F
}
"/"->{
temp=(countingA*1F / countingB*1F)
}
}
numberlist.removeAt(countFirstIndex)
numberlist.removeAt(countFirstIndex)
logiclist.removeAt(countFirstIndex)
numberlist.add(countFirstIndex,temp)
}
else{
//後加減
var countIndex=logiclist.indexOfFirst { it ->it=="+" || it=="-" }
countingA=numberlist[countIndex]
countingB=numberlist[countIndex+1]
if(countIndex>=0){
var temp:Float= 0F
when(logiclist[countIndex]){
"+"->{
temp=countingA*1F + countingB*1F
}
"-"->{
temp=(countingA*1F - countingB*1F)
}
}
numberlist.removeAt(countIndex)
numberlist.removeAt(countIndex)
logiclist.removeAt(countIndex)
numberlist.add(countIndex,temp)
}
}
}
return numberlist[0]
}
由於只是將邏輯實現,程式碼部分並沒有作優化。