藍橋演算法訓練 表示式計算
阿新 • • 發佈:2019-02-05
本文參考部落格http://www.cnblogs.com/z-y-p/p/3676945.html
問題描述 輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。 輸入格式 輸入一行,包含一個表示式。 輸出格式 輸出這個表示式的值。 樣例輸入 1-2+3*(4-5) 樣例輸出 -4 資料規模和約定 表示式長度不超過100,表示式運算合法且運算過程都在int內進行。思路:
之前刷題注重速度,許多問題不是十分透徹就上傳了,導致遺忘的很快。。。我在寫這道題的時候花費了
不少腦筋,下面我來講講思路
做此題第一步:
將中綴表示式轉換成字尾表示式,這個不能熟練轉換那麼這道題就沒法做,轉換方法參考這裡http://www.nowamagic.net/librarys/veda/detail/2307 網上有很多教程我就不重複了
會轉成字尾表示式後我們再來,以表示式2*(3+5)為例,用圖模擬程式碼執行過程
最開始將符號棧入一個“(”,防止棧空,會出錯
2進入數值棧
*號進符號棧
( 進符號棧
3進數值棧
+ 進符號棧
5進數值棧
檢測到"(" 不入棧, 而是將符號棧中的")" 之上的運算子提出來,供給棧頂次頂元素運算,並將棧頂和次頂兩個元素刪除得到的新的值存入數值棧,在將"("也刪掉,得到如圖
然後中綴表示式遍歷結束了,但還有8和2沒有通過*運算,這時候最開始通過strcat將“.”連線到中綴表示式後面
就起作用了,碰到“.”,就按碰到+-運算子的處理方案一樣,運算後如圖
最後在將數值棧棧頂取出列印就ok啦
程式碼
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<stack> using namespace std; stack<char> stack_ch;//符號棧 stack<int> stack_num; //數值棧 char str[1000]; //輸入的中綴表示式 char number[100]; //用來將字串中的數字變成int型的陣列 void js1()//這個函式只接收+-號,+-號等級最低,運算子棧中除了括號外 都可以取出運算 { int num1,num2; while (stack_ch.top()!='(') //從運算子棧中取一個運算子 對數值棧頂和次頂元素進行運算 { num1=stack_num.top();//取出一個數 stack_num.pop();//彈出這個數 num2=stack_num.top(); stack_num.pop(); switch (stack_ch.top()) { case '+': num2+=num1; break; case '-': num2-=num1; break; case '*': num2*=num1; break; case '/': num2/=num1; break; } stack_num.push(num2);//將計算結果入數值棧 stack_ch.pop();//刪除已經用過的符號 } } void js2()//只接收*/運算子 { int num1,num2; while (stack_ch.top()=='*' || stack_ch.top()=='/') //棧中只有*/優先順序大於*/ { num1=stack_num.top(); stack_num.pop(); num2=stack_num.top(); stack_num.pop(); switch (stack_ch.top()) { case '*': num2*=num1; break; case '/': num2/=num1; break; } stack_ch.pop(); stack_num.push(num2); } } int main() { int i,k=0,s; char c[5]="."; stack_ch.push('('); gets(str); strcat(str,c); for (i=0;str[i];i++) { if (str[i]>='0'&&str[i]<='9')//為數字 { number[k++]=str[i]; continue; } number[k]='\0'; //變成字串\0結尾 if (number[0]!='\0') { s=atoi(number); number[0]='\0'; stack_num.push(s); //將字串轉換成整型,放入數值棧中 } k=0; switch(str[i])//+-(這3個符號入js1函式,*/入js2函式 ,優先順序不同要分開計算 { case '+': js1(); stack_ch.push('+'); break; case '-': js1(); stack_ch.push('-'); break; case '*': js2(); stack_ch.push('*'); break; case '/': js2(); stack_ch.push('/'); break; case '(': stack_ch.push('('); break; case ')': js1(); stack_ch.pop(); break; case '.': { js1(); stack_ch.pop(); } } } printf("%d\n",stack_num.top()); }