题目
已知运算符的优先级为先算乘方(‘^’),再算乘除(‘*/‘),再算加减(‘±‘)。
输入包括一行,由数字和’()±*.^’和’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;
}