九度OJ题目1101-表达式求值

题目描述:

对于一个不存在括号的表达式进行计算

输入:

存在多种数据,每组数据一行,表达式不存在空格

输出:

输出结果

样例输入:

6/2+3+3*4

样例输出:

18

参考代码:

/*

题目信息不完整,虽然样例输入表达式中全为整型,结果也为整型,

但可能会出现输入,输出中均为浮点型

这里,代码1:默认输入为整型,输出为浮点型

代码2:表达式中也包含浮点型和括号,且表达式中无空格。

*/

代码1:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
using namespace std;
#define N 1001
char str[N];
int OP[4][4] = 
{0,0,0,0,
0,0,0,0,
1,1,0,0,
1,1,0,0};//+,-,*,/
int getOP(char c) {
	if (c == '+') return 0;
	else if (c == '-') return 1;
	else if (c == '*') return 2;
	else if (c == '/') return 3;
}

int main() {
	while (scanf("%s", str) != EOF) {
		int len = strlen(str);
		int i = 0;
		stack<double> num;
		stack<char> op;
		while (i < len) {		
			if (str[i] >= '0'&&str[i] <= '9') {
				int cnt = 0;
				while (str[i] != '\0'&&str[i] >= '0'&&str[i] <= '9') {
					cnt++;
					i++;
			   }
				double sum = 0, ans = 1;
				for (int j = cnt - 1; j >= 0; j--) {
					sum += (str[i-1-j] - '0')*ans;
					ans *= 10;
			   }
				num.push(sum);
				printf("*%d**%.2lf\n", cnt,num.top());
			}
			else {
				char c = str[i++];
				int idx = getOP(c);
				if (op.empty()) {
                    op.push(c);
                  //  printf("!!!%c\n", op.top());

				}
				else {
					//如果运算过程中出现栈为空,应该将判断栈是否为空放在前面,否则会出现栈溢出现象
					while(op.empty()==false && OP[getOP(op.top())][idx] == 1) {
						char c2 = op.top();
						op.pop();
						//printf("&&&&&&\n");
						double b = num.top();
						num.pop();
						double a = num.top();
						num.pop();
						double ret;
						if (c2 == '+') {
							ret = a + b;
						}
						else if (c2 == '-') {
							ret = a - b;
						}
						else if (c2 == '*') {
							ret = a*b;
						}
						else if (c2 == '/') {
							ret = a / b;
						}
						num.push(ret);
					//	printf("!!!%lf\n", num.top());

					}
					op.push(c);
					//printf("!!!%c\n", op.top());
				}
			}
		}
		while (!op.empty()) {
			char c2 = op.top(); op.pop();
			double b = num.top();
			num.pop();
			double a = num.top();
			num.pop();
			double ret;
			if (c2 == '+') {
				ret = a + b;
			}
			else if (c2 == '-') {
				ret = a - b;
			}
			else if (c2 == '*') {
				ret = a*b;
			}
			else if (c2 == '/') {
				ret = a / b;
			}
			num.push(ret);
		}
		printf("%.2lf\n", num.top());
	}
	return 0;
}

代码2:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<cstring>
using namespace std;

#define N 10001
char str[N];
char buf[N];

double to_double(char s[]) {//可能有小数点,可能没有,实际上已将包含整型的转化了
	double ret=0;
	int L1 = strlen(s);
	int mark = 0;
	bool flag = false;
	for (int i = 0; i < L1; i++) {
		if (s[i] == '.') {
			mark = i;
			flag = true;
			break;
		}
	}
	int tmp;
	//若没有小数点
	if (flag == false) {
		tmp= 1;
		for (int i =L1-1; i >= 0; i--) {
			ret = (s[i] - '0')*tmp;
			tmp *= 10;
		}
		return ret;
	}
	//计算小数点前的
    tmp = 1;
	for (int i = mark-1; i >=0; i--) {
		ret = (s[i] - '0')*tmp;
		tmp *= 10;
	}
	//计算小数点后的
	tmp = 1;
	for (int i = mark + 1; i < L1; i++) {
		ret = (s[i] - '0')*tmp;
		tmp /= 10;
	}
	return ret;
}
int getOp(char c) {
	if (c == '+')
		return 1 ;
	else if (c == '-')
		return 2;
	else if (c == '*')
		return 3;
	else if (c == '/')
		return 4;
	else if (c == '(')
		return 5;

}
int op[6][6] = {
	1,0,0,0,0,0,
	1,0,0,0,0,0,
	1,0,0,0,0,0,
	1,1,1,0,0,0,
	1,1,1,0,0,0,
	1,1,1,1,1,1
};
double calculate(double a, double b,char c) {
	if (c == '+')
		return a + b;
	else if (c == '-')
		return a - b;
	else if (c == '*')
		return a *b;
	else if (c == '/'&&b!=0)
		return a /b;
}
int main() {
	
	while (scanf("%s", str) != EOF) {
		int start, end;
		stack<double> num;
		stack<char> cal;
		int len = strlen(str);

		for (int i = 0; i < len; i++) {
			int flag1 = 0, flag2 = 0;
			//记录数字段所在的位置

			while ((str[i] >= '0'&&str[i] <= '9') || str[i] == '.') {
				if (flag1 == 0) start = i;
				flag1 = 1;
				end = i++;
				if (i >= len) flag2 = 1;
			}
			//对数字的处理
			if (flag1 == 1) {
				int cnt = 0;
				for (int i = start; i <= end; i++) {
					buf[cnt++] = str[i];
				}
				buf[cnt++] = '\0';
				double tem = to_double(buf);
				num.push(tem);
			}

			if (flag2) break;//若表达式只有一个数字是,便可直接退出,因此退出后要判断运算符栈是否为空

			//对运算符的处理
			if (cal.empty()) {
				cal.push(str[i]);
			}
		    else{
				if (str[i] != ')') {
					int flag = getOp(str[i]);
					if (flag == 1) {
							cal.push(str[i]);}
					else {
						char c1 = cal.top(); 
						cal.pop(); cal.push(str[i]);
						if (c1 != '(') {	
							double a1, b1;
							b1 = num.top(); num.pop();
							a1 = num.top(); num.pop();
							a1 = calculate(a1, b1,c1);
							num.push(a1);}}
				 }														
			}
		}

		while (!cal.empty()) {//
			char c1 = cal.top(); cal.pop();
			double a1, b1;
			b1 = num.top(); num.pop();
			a1 = num.top(); num.pop();
			a1 = calculate(a1, b1, c1);
			num.push(a1);
		}
		printf("%.6llf\n", num.top());
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sinat_38292108/article/details/88188748