表示式求值(棧)

2021-07-15 07:23:24 字數 2759 閱讀 1403

時間限制:

3000 ms  |  記憶體限制:

65535 kb

難度:4

描述

acm隊的mdd想做乙個計算器,但是,他要做的不僅僅是一計算乙個a+b的計算器,他想實現隨便輸入乙個表示式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。

比如輸入:「1+2/4=」,程式就輸出1.50(結果保留兩位小數)

輸入 第一行輸入乙個整數n,共有n組測試資料(n<10)。

每組測試資料只有一行,是乙個長度不超過1000的字串,表示這個表示式,每個表示式都是以「=」結束。這個表示式裡只包含+-*/與小括號這幾種符號。其中小括號可以巢狀使用。資料保證輸入的運算元中不會出現負數。

資料保證除數不會為0

輸出 每組都輸出該組表示式的運算結果,輸出結果保留兩位小數。

樣例輸入

2

1.000+2/4=

((1+2)*5+1)/4=

樣例輸出

1.50

4.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...