声明:我太菜了,求轻喷qwq
题目
这个是作业9的第五题
代码
/*
1 算式的输入
1.1 输入方式:从控制台键入一行字符串
1.2 支持数据类型:双精度浮点数(负数,如-x,请写为(0-x))
1.3 支持运算符:
1.3.1 加减乘除(注:+ - * /)
1.3.2 小括号
1.3.3 sin(x) cos(x) tan(x)(注:三角函数后面须带括号)
1.4 注意:程序没有进行对算式合法性的判断,所以请务必输入合法的算式,以免出现奇怪结果
1.5 样例输入输出
输入:sin(3.14/2*3)+2*3
输出:5
2 代码实现方式
2.1 加减乘除&括号:通过栈将算式转化为后缀表达式,使用链表储存(复制粘贴题目中的enum, union和struct)
2.2 三角函数;通过傻逼方法实现(对啊我就是菜)
*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
enum eType { DOUBLE, CHAR };
union uSymbol {
double Number;
char szOperator;
};
struct Node {
enum eType Type;
union uSymbol Symbol;
struct Node* next = NULL;
};
void Add(union uSymbol symbol, struct Node** head, struct Node** tail, enum eType type) {
//printf("BegAdd\n");
if (*head == NULL) {
struct Node* now;
if ((now = (struct Node*)malloc(sizeof(Node))) == NULL)exit(1);
*head = now;
*tail = now;
(*tail)->next = NULL;
now->Type = type;
now->Symbol = symbol;
//printf("endAddNULL\n");
return;
}
struct Node* now;
if ((now = (struct Node*)malloc(sizeof(Node))) == NULL)exit(1);
(*tail)->next = now;
*tail = now;
(*tail)->next = NULL;
now->Type = type;
now->Symbol = symbol;
// printf("endAdd\n");
}
double Getnum(char** s) {
double ans = 0;
while (**s >= '0' && **s <= '9') {
ans = ans * 10 + **s - '0';
(*s)++;
}
if (**s != '.')return ans;
double now = 0.1;
(*s)++;
while (**s >= '0' && **s <= '9') {
ans += now * ((double)**s - '0');
now *= 0.1;
(*s)++;
}
return ans;
}
int Priority(char c) {
if (c == '+' || c == '-')return 1;
if (c == '*' || c == '/')return 2;
return 0;
}
double Cal(char* s) {
struct Node* head = NULL;
struct Node* tail = NULL;
char stack[100];
int top = -1;
while (*s) {
int Pri = Priority(*s);
if (*s >= '0' && *s <= '9') {
double num = Getnum(&s);
union uSymbol now;
now.Number = num;
enum eType type = DOUBLE;
Add(now, &head, &tail, type);
}
else if (Pri) {
if (top == -1) { stack[++top] = *s; }
else {
while (top >= 0 && Priority(stack[top]) >= Pri) {
union uSymbol now;
now.szOperator = stack[top];
enum eType type = CHAR;
Add(now, &head, &tail, type);
top--;
}
stack[++top] = *s;
}
s++;
}
else if (*s == '(') {
stack[++top] = *s;
s++;
}
else if (*s == ')') {
while (top >= 0 && Priority(stack[top])) {
union uSymbol now;
now.szOperator = stack[top];
enum eType type = CHAR;
Add(now, &head, &tail, type);
top--;
}
top--;//弹出左括号
s++;
}
else if (*s == 's' || *s == 'c' || *s == 't') {
char tag = *s;
//printf("in!\n");
int tot = 0, num = 0;
s += 3;
char* p = s;
char ss[100];
do{
ss[num++] = *p;
if (*p == '(')tot++;
if (*p == ')')tot--;
p++;
} while (tot);
ss[num] = '\0';
//printf("NowCalkid %s\n",s);
double kid = Cal(ss);
//printf("OKNowCalkid %lf\n",kid);
switch (tag) {
case 's':kid = sin(kid); break;
case 'c':kid = cos(kid); break;
case 't':kid = tan(kid); break;
}
union uSymbol now;
now.Number = kid;
enum eType type = DOUBLE;
Add(now, &head, &tail, type);
s = p;
}
}
while (top>=0) {
union uSymbol now;
now.szOperator = stack[top];
enum eType type = CHAR;
Add(now, &head, &tail, type);
top--;
}
//std::cout << top << std::endl;
struct Node* now = head;
double tocal[100];
int topcal = -1;
while(1) {
//printf("whilebegin\n");
if (now == NULL)return tocal[topcal];//若算式不合法,就炸了
//printf("returned\n");
if (now->Type == DOUBLE) {
//std::cout << "hahaddd\n";
tocal[++topcal] = now->Symbol.Number;
//printf("%g\n", tocal[topcal]);
}
else if (now->Type == CHAR) {
//std::cout << "hahaccc\n";
char c = now->Symbol.szOperator;
//printf("%c\n", c);
switch (c) {
case '+':tocal[topcal - 1] = tocal[topcal - 1] + tocal[topcal]; break;
case '-':tocal[topcal - 1] = tocal[topcal - 1] - tocal[topcal]; break;
case '*':tocal[topcal - 1] = tocal[topcal - 1] * tocal[topcal]; break;
case '/':tocal[topcal - 1] = tocal[topcal - 1] / tocal[topcal]; break;
}
topcal--;
//printf("%g\n", tocal[topcal]);
}
//std::cout << "hahaout\n";
now = now->next;
}
}
int main() {
char s[100];
scanf("%s", s);
printf("%g\n", Cal(s));
}