NYOJ--字首式計算

jsjliuyun發表於2014-04-17

字首式計算

時間限制:1000 ms  |  記憶體限制:65535 KB
難度:3
描述

先說明一下什麼是中綴式:

如2+(3+4)*5這種我們最常見的式子就是中綴式。

而把中綴式按運算順序加上括號就是:(2+((3+4)*5))

然後把運算子寫到括號前面就是+(2 *( +(3 4) 5) )

把括號去掉就是:+ 2 * + 3 4 5

最後這個式子就是該表示式的字首表示。

給你一個字首表示式,請你計算出該字首式的值。

比如:

+ 2 * + 3 4 5的值就是 37

輸入
有多組測試資料,每組測試資料佔一行,任意兩個操作符之間,任意兩個運算元之間,運算元與操作符之間都有一個空格。輸入的兩個運算元可能是小數,資料保證輸入的數都是正數,並且都小於10,運算元數目不超過500。
以EOF為輸入結束的標誌。
輸出
對每組資料,輸出該字首表示式的值。輸出結果保留兩位小數。
樣例輸入
+ 2 * + 3 4 5
+ 5.1 / 3 7
樣例輸出
37.00
5.53
來源

經典題目

解析:前面一直在研究中綴表示式和字尾表示式,這次做做字首表示式,不過思想還是一樣的,逆序著判斷幾種情況做不同的操作,存入運算元棧,然後將運算元棧頂兩元素與當前遇到的操作符計算即可,廢話不說直接上程式碼,程式碼註釋我覺得還是很詳細的哈!

#include <iostream>
#include <stack>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using std::endl;
using std::cin;
using std::cout;
using std::string;
using std::stack;
double compute(double a,double b,char ch)
{
	switch(ch)
	{
	case '+':
		return a+b;
	case '-':
		return a-b;
	case '*':
		return a*b;
	case '/':
		return a/b;
	}
}
//判斷是否為操作符
int isDigit(char ch)
{
	if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
	{
		return 1;
	}else{
		return 0;
	}
}
int main()
{
	string str;
	stack<double> numstack;
	//讀取一行字串
	while(getline(cin , str))
	{
		string res;
		for(int i=str.length()-1;i>=0;--i)
		{//將運算元入棧
			if(isDigit(str[i]))
			{//如果當前字元是操作符
				//從運算元棧中棧頂提取兩個數進行運算
				double t1=numstack.top();
				numstack.pop();
				double t2=numstack.top();
				numstack.pop();
				double result=compute(t1,t2,str[i]);
				numstack.push(result);
			}else if(str[i]==' ')
			{//當前字元是空格不做處理

			}else{
				//當前字元是數字或者小數點
				res+=str[i];
				//判斷當前res中儲存的字串是否為一個單獨的數
				if((i>0&&str[i-1]==' ')||(i==0))
				{//如果前一個字元是空格的話則是一個單獨的數
					reverse(res.begin(),res.end());
					//轉換為double型別的數
					double temp=atof(res.c_str());
					numstack.push(temp);
					//重置res字串
					res.clear();
				}
			}
		}
		printf("%.2f\n",numstack.top());
		//清空棧
		while(!numstack.empty())
		{
			numstack.pop();
		}
	}
	return 0;
}

相關文章