時間限制:
3000 ms | 記憶體限制:
65535 kb
難度:4
描述
acm隊的mdd想做乙個計算器,但是,他要做的不僅僅是一計算乙個a+b的計算器,他想實現隨便輸入乙個表示式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。
比如輸入:「1+2/4=」,程式就輸出1.50(結果保留兩位小數)
輸入 第一行輸入乙個整數n,共有n組測試資料(n<10)。
每組測試資料只有一行,是乙個長度不超過1000的字串,表示這個表示式,每個表示式都是以「=」結束。這個表示式裡只包含+-*/與小括號這幾種符號。其中小括號可以巢狀使用。資料保證輸入的運算元中不會出現負數。
資料保證除數不會為0
輸出 每組都輸出該組表示式的運算結果,輸出結果保留兩位小數。
樣例輸入
21.000+2/4=
((1+2)*5+1)/4=
樣例輸出
1.504.00
這個使用到了棧:
首先定義了兩個棧點,乙個是放字元的棧點,乙個是放資料的棧點。
並且在每乙個放字元的棧點都在其首端放上了個「(」左括號,在末端放上乙個「)」右括號。
**中只有乙個for迴圈,每次執行一次,要記住,字串是從第二個開始讀取的,記錄字串的長度也是s1之後的長度。
講解下**的執行過程吧:
看例子(((1+2)*5+1)/4)
第一次迴圈讀取的是(,那麼就把(壓棧到字元棧裡面
第二次迴圈讀取的是(,就把(壓棧到字元棧裡
第三次迴圈讀取的還是(,繼續吧(壓棧到字元棧裡
第四次迴圈讀取到了數字1,進行判斷是不是小數,判斷後(稍後講解如何判斷小數部分)不是小數,就把數字1壓棧到數字棧裡面。
第五次迴圈,讀取到了字元+,進入while()中,因為不滿足while迴圈的條件,因為此時的棧裡面只有(((,這時再把字元+壓棧到字元棧裡面;
第六次迴圈,讀取到了數字2,判斷後把2壓棧到了資料棧裡面;
第七次迴圈,讀取到了字元),滿足while迴圈裡的條件因為此時字元棧裡面放的是(((+,滿足while條件後,取資料棧棧頂元素2賦值給a,然後刪除棧頂元素,
然後繼續取資料棧棧頂元素1賦值給b,然後刪除棧頂元素,進入swith()分支語句中,switch語句裡面取字元棧頂元素,我們取到了字元+,c=a+b,得到3,
然後把3存到資料棧中,也就是把3壓棧到資料棧中後,刪除字元棧,就是刪除我們運算過的字元+,然後再刪除字元棧棧頂元素,也就是刪除字元(,此時的字元棧裡面是((;
接著進行下一輪的迴圈
第八次迴圈,讀取的是字元*,然後把字元*壓棧到字元棧裡面,
第九次迴圈,讀取到數字5,判斷後,把5壓棧到資料棧中
第十次迴圈,讀取到了字元+,滿足while迴圈後根據裡面的流程走,把資料棧裡的資料取出後刪除棧頂元素把計算結果15壓棧到資料棧中把字元棧棧頂元素*刪除,最後再把字元+壓棧到字元棧中
第十一次迴圈讀取到數字1,判斷後壓棧到資料棧此時的資料站裡面有15和1,
第十二次迴圈讀取到了),滿足while條件,再次進行取棧頂元素刪除棧頂元素的操作,
把計算結果16放進資料棧裡之後刪除字元棧中運算過的字元+,再次刪除棧頂元素),此時的字元棧裡面只有乙個」(「
第十三次迴圈讀取到了字元/,把字元/壓棧到字元棧裡面,字元棧裡面此時有(/
第十四次迴圈讀取數字4,判斷後放入資料棧中
第十五次迴圈讀取到字元),滿足while條件進行取棧頂元素刪除棧頂元素,將計算結果4放入資料棧中後,刪除運算過的字元/,最後再刪除棧頂元素(,此時迴圈結束,輸出資料棧中棧頂元素。此時字元棧為空,資料棧也只有乙個元素。
這就是整個程式過程,別只是看看,看著解析動手畫畫,畫兩個陣列。根據程式步驟放元素取元素刪除元素。
關於判斷小數點的那一部分是,b記錄下來的是小數點的位置,
例如1.000讀入進去後,記得小數點位置是b=1,v=1000之後i++往後走加到了i=5的時候不是數字和小數點了,退出while迴圈,i--,i=4,那麼i-b=(4-1)=3,說明小數點後面有3位數,
b!=0,說明是小數,v/10*3就是小數1.000了,動手試試。
#include#include#include#includeusing namespace std;
char s[1010];
stackshuju;
stackzifu;
int main()
else if(s[i]>='0'&&s[i]<='9')
i--;
if(b!=0)
else
shuju.push(v);
}else if(s[i]=='+'||s[i]=='-')
shuju.push(c);
zifu.pop();
} zifu.push(s[i]);
}else if(s[i]=='*'||s[i]=='/')
else if(zifu.top()=='/')
zifu.push(s[i]);
} else if(s[i]==')')
shuju.push(c);
zifu.pop();
} zifu.pop();}}
printf("%.2lf\n",shuju.top());
shuju.pop();
}return 0;
}
壓棧,取棧頂元素,和刪除棧頂元素是name.push(),name.top(),mane.pop()
棧 表示式求值
核心演算法思想 1.運用兩個棧,乙個存運算子,乙個存數值 2.以 做為標誌位,開頭或者結尾 3.檢查當前字元,若當前字元為數值,則加入數值棧,若為運算子,則檢驗當前運算子的優先順序,1 若當前運算子優先順序大於棧頂優先順序,則把該運算子壓入棧 2 若當前運算子優先順序等於棧頂優先順序 括號的情況 則...
棧 表示式求值
把運算的處理專門放在乙個函式裡,然後通過優先順序的判斷去呼叫函式,注意那個 還是放在else if裡面吧,不要和運算混在一起了 includeusing namespace std const int n 1e5 10 stacks1 stacks2 int flag 0 處理 四個 mapcmp ...
棧應用 表示式求值
include stdafx.h include using namespace std const int explenght 20 const int stack init size 20 const int stack incrment 10 templateclass stack stack...