1. 程式人生 > >HDU-1237- 簡單計算器--棧的基本應用

HDU-1237- 簡單計算器--棧的基本應用

++ 現在 amp hdu print 簡單 循環條件 har pop

簡單計算器

Problem Description 讀入一個只包含 +, -, *, / 的非負整數計算表達式,計算該表達式的值。 Input 測試輸入包含若幹測試用例,每個測試用例占一行,每行不超過200個字符,整數和運算符之間用一個空格分隔。沒有非法表達式。當一行中只有0時輸入結束,相應的結果不要輸出。 Output 對每個測試用例輸出1行,即該表達式的值,精確到小數點後2位。 Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00 13.36 ————————————————————————————————————————————————————分割線

簡單分析:

  棧的基本應用,模擬計算機的底層計算功能。非負整數表示0也可出現在表達式中,小數點後兩位表示需要用double類型來存儲數據。

  這類問題轉化為後綴表達式來做,更常規正式點,編寫速度更快;不過,我還是用基本兩個棧的模擬,先大致理清幾類思路,然後嘗試編程,才測試各種自造地合理的盡可能全面的樣例:哪裏有bug就去補哪裏。(如果思路沒有理清,比較費時間吧!簡單題貌似還好說!)

  代碼裏的註釋給的比較詳細,自己點開看看。給出下面幾組參考數組,只要可以正確基本可以AC:

  1 + 2
  1 + 2 * 3 - 4 / 5
  1111+220/220*1+1*1*0
  2*2*2/8-4+5/5/5*5
  16*8/4+7-3/3*9
  0-8+9

  

技術分享圖片
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<stack>
  7 using namespace std;
  8 #define N 60010
  9 stack<double>num; double arr1[211];   //存儲數字的棧,arr1[]存貯分離出來的數字
 10 stack<char
>op;double arr2[211]; //存貯運算符的棧 ,arr2存貯分離出來的運算符 11 12 int pos1,pos2; //pos1和POS2分別表示arr1和arr2的長度 13 char str[300]; //輸入數據時的原字符串 14 15 void fact1() //將字符串中的數字和運算符提取出來存放進數組裏 16 { 17 int i=0; 18 int len=strlen(str); 19 pos1=pos2=0; 20 while(i<len) 21 { 22 while(i<len&&str[i]== )i++; //處理空格 23 if(i==len)break; 24 if(str[i]>=0&&str[i]<=9) //分離數字(比如1234,1後面肯定是數字,4後面不是數字) 25 { 26 double sum=0.0; 27 for(; i<len&&str[i]>=0&&str[i]<=9; i++) 28 sum=sum*10.0+str[i]-0; 29 arr1[pos1++] = 1.0*sum; 30 } 31 else //分離字符 32 { 33 arr2[pos2++]=str[i++]; 34 } 35 } 36 } 37 void solve() 38 { 39 fact1(); //處理字符串 40 char nowop; 41 int p1=0; //指向arr1的要使用時的數字下標,初始時為0表示最早從arr1【0】開始 42 int p2=0; //指向arr2的要使用時的字符的下標, 43 num.push(arr1[p1++]); 44 op.push(arr2[p2++]); 45 while(p1<pos1||p2<pos2||num.size()>=2) //判斷循環條件 46 { 47 while(num.size()<2&&p1<pos1) //維持數字棧中保留兩個 48 num.push(arr1[p1++]); 49 if(p2<pos2&&op.empty()) //維持運算符棧中保留1個運算符 50 op.push(arr2[p2++]); 51 52 if(op.top()==*||op.top()==/) //直接可以進行運算,如3*7/8+4 時,3*7可直接算 53 { 54 double n1,n2; 55 n1=num.top();num.pop(); 56 n2=num.top();num.pop(); 57 nowop=op.top();op.pop(); 58 if(nowop==*) 59 num.push(n2*n1); 60 else 61 num.push(n2/n1); 62 } 63 //棧外的運算符級別高,例如3+5*8時,‘’*‘’級別大於‘’+‘’ 64 else if(p2<pos2&&(nowop=arr2[p2])&&(nowop==*||nowop==/)&&(op.top()==+||op.top()==-)) 65 { 66 double s1; 67 if(nowop==*) 68 s1=num.top()*arr1[p1++]; 69 else 70 s1=num.top()/arr1[p1++]; 71 num.pop(); 72 num.push(s1); 73 p2++; //運算符數組指向下一位 74 } 75 else //棧外的運算符等級與棧內相等,或者無運算符,例如5+9-6,’-‘號相對’+‘平級 76 { 77 double n1,n2; 78 n1=num.top();num.pop(); 79 n2=num.top();num.pop(); 80 nowop=op.top();op.pop(); 81 if(nowop==-) 82 num.push(n2-n1); 83 else 84 num.push(n1+n2); 85 } 86 } 87 printf("%.2lf\n",num.top()); 88 } 89 int main() 90 { 91 while(gets(str),str[0]!=0||strlen(str)!=1) 92 //謹防樣例:0+0(也就說以0開頭的式子也合法,這時需要再判一下長度!) 93 { 94 while(!num.empty()) 95 num.pop(); 96 while(!op.empty()) 97 op.pop(); 98 solve(); 99 } 100 return 0; 101 }
View Code

HDU-1237- 簡單計算器--棧的基本應用