表达式求值(+-*/^,栈)

题目

已知运算符的优先级为先算乘方(‘^’),再算乘除(‘*/‘),再算加减(‘±‘)。

输入包括一行,由数字和’()±*.^’和’sin’,’cos’组成,并以’#’结果。保证表达式合法,所有运算在double的精度范围之内。

输出一个小数,表示表达式的值。保留三位有效数字。

示例

70+cos(3+2/2/3^2-1)*(4-3)#

69.486

代码
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cmath>
#define Init_Size 120
using namespace std;
typedef struct {
	char ch[Init_Size];
	double  doub[Init_Size];
	int topch;
	int topdo;
	int stacksize;
} SqStack;
bool StackEmpty(SqStack *S) {
	return S -> topch == 0 && S -> topdo == 0;
}
void InitStack(SqStack *S) {
	S -> topch = S -> topdo = 0;
	S -> stacksize = Init_Size;
	return ;
}
void PushCh(SqStack *S, char x) {
	//printf ("Push %c\n", x);
	S -> ch[S -> topch++] = x;
	return ;
}

void PushDo(SqStack *S, double x) {
	//printf ("Push %c\n", x);
	S -> doub[S -> topdo++] = x;
	return ;
}
char PopCh(SqStack *S) {
	//printf ("Pop\n");
	if (S -> topch) {
		char x = S -> ch[-- S -> topch];
		return x;
	}
	return -1;
}

double PopDo(SqStack *S) {
	//printf ("Pop\n");
	if (S -> topdo) {
		double x = S -> doub[-- S -> topdo];
		return x;
	}
	return -1;
}
char TopCh(SqStack *S) {
	if (S -> topch)
		return S -> ch[S -> topch - 1];
}

double TopDo(SqStack *S) {
	if (S -> topdo)
		return S -> doub[S -> topdo - 1];
}
int find(char op) {
	if (op == '(') return 0;
	if (op == '+' || op == '-') return 1;
	if (op == '*' || op == '/') return 2;
	if (op == '^') return 3;
	if (op == 'c' || op == 's') return 4;
	if (op == ')') return 5;
	return -1;
}
char check(char a, char b) {
	int pa = find(a);
	int pb = find(b);
	if (pa == pb) {
		if (a == '#') return '=';
		if (a != '(') return '>';
		return '<';
	} else {
		if (a == '(' && b == ')') return '=';
		if (b == '(') return '<';
		if (b == ')') return '>';
		if (pa > pb) return '>';
		if (pa < pb) return '<';
	}
}
double work(double a, double b, char c) {
	if (c == '+') return a + b;
	if (c == '-') return a - b;
	if (c == '*') return a * b;
	if (c == '/') return a / b;
	if (c == '^') return pow(a, b);
}
double cal() {
	SqStack *nums = NULL;
	SqStack *ops = NULL;
	nums = (SqStack *)malloc(sizeof(SqStack));
	ops = (SqStack *)malloc(sizeof(SqStack));
	PushCh(ops, '#');
	PushCh(ops, '+');
	PushDo(nums, (double)0.0);
	char c = getchar();
	while (c != '#' || TopCh(ops) != '#') {
		//cout << c << endl; 
		if (isdigit(c)){
			double num(0);
			double k(0.1);
			for (; isdigit(c); c = getchar()) num = num * 10 + c - 48;
			if (c == '.') {
				c = getchar();
				for (; isdigit(c); c = getchar()) {
					num += k * (c - 48);
					k /= 10;
				}
			}
			PushDo(nums, num);
			//cout << num << endl;
		} else {
			if (c == 'c' || c == 's') {
				if (TopCh(ops) == '(') {
					PushCh(ops, '+');
					PushDo(nums, (double)0.0);
				}
				PushCh(ops, c);
				c = getchar();
				c = getchar();
				c = getchar();
				continue;
			} else {
				char rela = check(TopCh(ops), c);
				switch (rela) {
					case '<':
						PushCh(ops, c);
						c = getchar();
						break;
					case '=':
						PopCh(ops);
						c = getchar();
						break;
					case '>':
						char op = TopCh(ops); PopCh(ops);
						if (op == 'c' || op == 's') {
							char op2 = TopCh(ops); PopCh(ops);
							double a = TopDo(nums); PopDo(nums);
							double b = TopDo(nums); PopDo(nums);
							if (op == 'c') a = cos(a);
							if (op == 's') a = sin(a);
							double cc = work(b, a, op2);
							PushDo(nums, cc);
						} else {
							double a = TopDo(nums); PopDo(nums);
							double b = TopDo(nums); PopDo(nums);
							double cc = work(b, a, op);
							PushDo(nums, cc);
						}
						break;
				}
			}
		}

	}
	double ans = TopDo(nums);
	free(ops);
	free(nums);
	return ans;
}
int main() {
	//freopen("in.txt", "r", stdin);
	double ans = cal();
	printf ("%.3f\n", ans);
	return 0;
}

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页