表達式求值 nyoj

表達式求值

時間限制: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>
#include <stdlib.h>
#define Max_len 1010
#define NUM 1000000

double number[Max_len];
double sign[Max_len];
int get_pri(int n); //quanxian
double jisuan (double a, double b, double c);
void sub_result(int front_num);
void postfix (char ch[], int * front_num);

int main (){

	char ch[Max_len];
	int d;
	int front_num = 0;
	
	scanf("%d", &d);
	while (d--) {
		front_num = 0;
		scanf("%s", ch);
		postfix(ch, &front_num);
		sub_result(front_num);
	}
	return 0;
}

void postfix(char ch[], int *front){
	
	int front_sign = 0, front_num =  *front;
	int len = strlen (ch);
	int i, x = 10;
	double flag = 0.1;

	for(i = 0; i < len - 1; i++) {
		if(ch[i] >= '0' && ch[i] <= '9') {
			number[front_num ++] = ch[i] - '0';
			
			for(i += 1; '0' <= ch[i] && ch[i] <= '9'; i++ ){
				number[front_num - 1] = number[front_num - 1] * x + ch[i] - '0';	
			}
			i--;
			if(ch[i + 1] == '.') {
				for(i += 2; ch[i] >= '0' && ch[i] <= '9'; i++) {
					number[front_num - 1] += flag * (ch[i] - '0');
					flag *= 0.1;
				}
				i--;
				flag = 0.1;
			}
		}
		else if(ch[i] == ')'){
			while (sign[front_sign - 1] != NUM + '(' ){
				number[front_num ++] = sign[front_sign - 1];
				front_sign --;
			}
			front_sign --;
		}
		else if(ch[i] == '('){
			sign[front_sign ++] = ch[i] + NUM;
		} 
		else {
			
			while (get_pri(sign[front_sign - 1]) >= get_pri(ch[i] + NUM)){
				number[front_num ++] = sign[front_sign - 1] ;
				front_sign --;
			}
				sign[front_sign ++] = ch[i] + NUM;	
		}
		
	}
	while(front_sign > 0) {
		number[front_num ++] = sign[--front_sign];
	}
	*front = front_num;
}


int get_pri(int n){
	
	if(n == (NUM + '+') || n == (NUM + '-')){
		return 1;
	}
	if(n ==( NUM + '*') || n == (NUM +'/')){
		return 2;
	}
	else {
		return 0;
	}
}

void sub_result(int front_num){
	
	int k = front_num, i, m = 0;
	double record[Max_len];

	for(i = 0; i < k; i++) {
		if(number[i] < NUM){
			record[m] = number[i];
			m++;
		}
		else{
			record[m - 2] = jisuan (record[m - 2], record[m - 1], number[i]);
			m --;
		}
	}
	printf("%.2lf\n", record[0]);
}

double jisuan (double a, double b, double c){
	
	if(c - NUM == '+') {
		return a + b;
	}
	if(c - NUM == '-'){
		return a - b;
	}
	if(c - NUM == '/'){
		return a / b;
	}
	if(c - NUM == '*' ){
		return a * b;
	}
}        


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章