1. 程式人生 > >HDU1237簡單計算器-中綴表示式-字尾表示式

HDU1237簡單計算器-中綴表示式-字尾表示式

簡單計算器

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11355    Accepted Submission(s): 3697

Problem Description 讀入一個只包含 +, -, *, / 的非負整數計算表示式,計算該表示式的值。  Input 測試輸入包含若干測試用例,每個測試用例佔一行,每行不超過200個字元,整數和運算子之間用一個空格分隔。沒有非法表示式。當一行中只有0時輸入結束,相應的結果不要輸出。 Output 對每個測試用例輸出1行,即該表示式的值,精確到小數點後2位。 Sample Input 1 + 2 4 + 2 * 5 - 7 / 11 0 Sample Output 3.00 13.36 Source 思路:
        對於中綴表示式的運算一般要轉化成字尾表示式再作運算,開兩個棧,一個作為運算元棧StackDigital,一個作為操作符棧StackOperator。 1.定義一個函式判定優先順序:# 的優先順序最低,為0,+ 和 - 的級別相同且高於 #,標為1,* 和 / 的級別相同且高於 + 和 - ,標誌為2, 2.先往運算子棧放入一個 # (標定界限),表示式最後也加一個 #( (標定界限)), 3.遍歷表示式,若讀到數字,則以數字型別輸入,直接放到運算元棧,若讀到的是運算子,則比較讀到的運算子與運算子棧頂符號的級別, 若比棧頂的高,則入棧,否則,從數棧取兩個運算元根據操作符棧頂的操作進行運算,再把結果壓入數棧,剛剛讀到的運算子再與現在運算子棧
頂元素的級別進行比較……最後數剩下的一個元素,就是結果。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <ctype.h>
using namespace std;

double stDit[300];
char stOp[300],str[300];
int top1,top2;

int Priority(char op)
{
	if (op=='#') 
		return 0;
	if (op=='+' || op=='-') 
		return 1;
	if (op=='*' || op=='/')
		return 2;
	else
		return -1;
}
double Operate(double x,double y,char op)
{
	if (op=='+') return x+y;
	if (op=='-') return x-y;
	if (op=='*') return x*y;
	if (op=='/') return x/y;
	else return -1;
}

double Calc()
{
	double x,y,tmp;
	char op;
	int i,n = strlen(str);

	top1 = top2 = -1;
	stOp[++top2] = '#';
	str[n++] = '#';

	for(i=0; i < n; ++i)
	{
		if (str[i]==' ')
			continue;
		if (isdigit(str[i]))				//是數字
		{
			sscanf(str+i,"%lf",&tmp);
			stDit[++top1] = tmp;			//stack push

			while(isdigit(str[i+1]))		//+1很重要
				++i;
		}
		else								//是操作符
		{
			while (Priority(stOp[top2]) >= Priority(str[i]))//如果操作棧頂的操作符優先順序高,則作+-*/運算
			{
				if (str[i]=='#' && stOp[top2]=='#')
					return stDit[top1];
				y = stDit[top1--];
				x = stDit[top1--];
				op = stOp[top2--];
				stDit[++top1] = Operate(x,y,op);
			}
			stOp[++top2] = str[i];			//如果新操作符優先順序高,str[i]進棧
		}
	}
	return stDit[top1];
}
int main()
{
	int i;
	while (gets(str) != NULL && strcmp(str,"0")!=0)
	{
		printf("%.2lf\n",Calc());
	}
	return 0;
}