1696:逆波蘭表達式
- 總時間限制:
- 1000ms
- 內存限制:
- 65536kB
- 描述
- 逆波蘭表達式是一種把運算符前置的算術表達式,例如普通的表達式2 + 3的逆波蘭表示法為+ 2 3。逆波蘭表達式的優點是運算符之間不必有優先級關系,也不必用括號改變運算次序,例如(2 + 3) * 4的逆波蘭表示法為* + 2 3 4。本題求解逆波蘭表達式的值,其中運算符包括+ - * /四個。
- 輸入
- 輸入為一行,其中運算符和運算數之間都用空格分隔,運算數是浮點數。
- 輸出
-
輸出為一行,表達式的值。
可直接用printf("%f\n", v)輸出表達式的值v。 - 樣例輸入
-
* + 11.0 12.0 + 24.0 35.0
- 樣例輸出
-
1357.000000
- 1、本題的題目錯了,這應該是波蘭表達式,也叫做前綴表達式。逆波蘭表達式是后綴表達式,即操作符在數字的后面
- 2、前綴表達式:http://baike.so.com/doc/6896516-7114163.html
- 前綴表達式的計算方法:從右往左掃描表達式,只要碰到數字就入棧;碰到運算符,彈出棧頂的兩個數字運算,注意如果是減號或除號,要用 棧頂數字 除或減 次棧頂數字。
-
3、本題為了方便操作,可以從左往右分別記錄了第幾個元素是哪個數字或是哪個運算符。分別存儲在tmp[]、num[]中,但記錄下標時,兩個數組共用1個sum。
所以判斷第i個是數字還是運算符時,首先給num[]賦一個極值,然后判斷如果num[]是極值,那么第i個是運算符,如果不是極值,那就是數字。注意極值不能為0,因為給出的數字可能為04、可以使用atof(str)把字符串轉換為一個double類型的浮點數。atof定義在cmath中。待轉換的字符串要用char數組存儲,一定要注意下標從0開始,小數點也要存到char數組里。例:char a[20]=“123.456”;double l=atof(a);輸出結果為123.456
#include<cmath> #include<iostream> #include<cstring> #include<cstdio> #include<cstdlib> #define no -999999999 using namespace std; char k[1001]; char s[1001],tmp[1001]; double num[1001]; int l=-1,sum,top; double stack[1001],ans; int main() { gets(s); for(int i=1;i<=1000;i++) num[i]=no;//num數組賦極值 for(int i=0;i<=strlen(s);i++) { if(s[i]==42||s[i]==43||s[i]==45||s[i]==47) tmp[++sum]=s[i];//運算符 else if((s[i]>='0'&&s[i]<='9')||s[i]==46) k[++l]=s[i];//數字或者小數點 else if(s[i-1]>='0'&&s[i-1]<='9') //只有數字之后的空格才需要把字符串轉換成數字 { num[++sum]=atof(k); memset(k,'\0',sizeof(k)); l=-1;//l從-1開始,因為上面k[++l]=s[i],數組k從0開始賦值 } } for(int i=sum;i>0;i--)//從右往左掃描 { if(num[i]!=no) stack[top++]=num[i];//不是極值,是數字,入棧 else //運算符,彈出棧頂兩個數字運算 { double a=stack[--top],b=stack[--top]; switch(tmp[i]) { case '+':ans=a+b;break; case '-':ans=a-b;break; case '*':ans=a*b;break; case '/':ans=a/b;break; } stack[top++]=ans;//運算完結果入棧 } } printf("%f\n",stack[0]); }