表達式求值(二)

表達式求值
時間限制:3000 ms  |  內存限制:65535 KB
難度:4
描述
ACM隊的mdd想做一個計算器,但是,他要做的不僅僅是一計算一個A+B的計算器,他想實現隨便輸入一個表達式都能求出它的值的計算器,現在請你幫助他來實現這個計算器吧。
比如輸入:“1+2/4=”,程序就輸出1.50(結果保留兩位小數)
輸入
第一行輸入一個整數n,共有n組測試數據(n<10)。
每組測試數據只有一行,是一個長度不超過1000的字符串,表示這個運算式,每個運算式都是以“=”結束。這個表達式裏只包含+-*/與小括號這幾種符號。其中小括號可以嵌套使用。數據保證輸入的操作數中不會出現負數。
數據保證除數不會爲0
輸出
每組都輸出該組運算式的運算結果,輸出結果保留兩位小數。
樣例輸入
2
1.000+2/4=
((1+2)*5+1)/4=
樣例輸出
1.50
4.00
 
#include <stdio.h>
#include <string.h>

#define M 1000

typedef struct data
{
	double digital[M];
	int top;
}Data;

typedef struct Str
{
	char string[M];
	int top;
}Str;

void pop_data(Data *p, char s);
void pop_str(Str *p);

int main()
{
	int n = 0, i = 0, lens = 0, j;
	double d = 0;
	char s[M], a[M];
	Data data;
	Str str;

	scanf("%d", &n);
	getchar();

	while(n--)
	{
		str.top = 0;
		data.top = 0;
		memset(str.string, '\0', M);
		memset(data.digital, -1, M);
		str.string[0] = '=';
		str.top++;

		memset(s, '\0', M);
		memset(a, '\0', M);

		gets(s);
		lens = strlen(s);

		j = 0;
		for(i = 0; i < lens; i++)
		{
			if((s[i] >= '0' && s[i] <= '9') || s[i] == '.' )
				a[j++] = s[i];			
			else if(s[i] == '*' || s[i] == '/')
			{	
				if(a[0] != '\0')
				{
					sscanf(a, "%lf", &d);
					data.digital[data.top++] = d;
					memset(a, '\0', M);
					j = 0;
				}
				if(str.string[str.top - 1] == '*' || str.string[str.top - 1] == '/')
				{
					pop_data(&data, str.string[str.top - 1]);
					pop_str(&str);
				}
				str.string[str.top++] = s[i];
			}
			else if(s[i] == '(')
				str.string[str.top++] = s[i];
			else if(s[i] == '+' || s[i] == '-' || s[i] == '=')
			{
				if(a[0] != '\0')
				{
					sscanf(a, "%lf", &d);
					data.digital[data.top++] = d;
					memset(a, '\0', M);
					j = 0;
				}
				if(str.string[str.top - 1] == '*' || str.string[str.top - 1] == '/' || s[i] == '=')
				{
					pop_data(&data, str.string[str.top - 1]);
					pop_str(&str);
				}
				else if(str.string[str.top - 1] == '+' || str.string[str.top - 1] == '-')
				{
					pop_data(&data, str.string[str.top - 1]);
					pop_str(&str);
				}				
				if(s[i] == '=' && str.string[str.top - 1] != '=')
				{
					pop_data(&data, str.string[str.top - 1]);
					pop_str(&str);
				}
				if(str.string[str.top - 1] == '+' || str.string[str.top - 1] == '-')
				{
					pop_data(&data, str.string[str.top - 1]);
					pop_str(&str);
				}
				str.string[str.top++] = s[i];
			}
			else if(s[i] == ')')
			{
				if(a[0] != '\0')
				{
					sscanf(a, "%lf", &d);
					data.digital[data.top++] = d;
					memset(a, '\0', M);
					j = 0;
				}
				pop_data(&data, str.string[str.top - 1]);
				str.string[str.top - 1] = '\0';
				if(str.string[str.top - 2] != '(')
				{
					pop_data(&data, str.string[str.top - 2]);
					pop_str(&str);
				}
				str.string[str.top - 1] = '\0';
				str.string[str.top - 2] = '\0';
				str.top -= 2;
			}
		}
		printf("%.2f\n", data.digital[0]);
	}

	return 0;
}

void pop_data(Data *p, char s)
{
	switch(s)
	{
	case '+': p->digital[p->top - 2] = p->digital[p->top - 2] + p->digital[p->top - 1]; break;
	case '-': p->digital[p->top - 2] = p->digital[p->top - 2] - p->digital[p->top - 1]; break;
	case '*': p->digital[p->top - 2] = p->digital[p->top - 2] * p->digital[p->top - 1]; break;
	default : p->digital[p->top - 2] = p->digital[p->top - 2] / p->digital[p->top - 1];
	}
	p->digital[p->top - 1] = -1;
	p->top--;
}

void pop_str(Str *p)
{
	p->string[p->top - 1] = '\0';
	p->top--;
}
        


發佈了39 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章