zoukankan      html  css  js  c++  java
  • C语言_通过链表和栈实现简易计算器

    声明:我太菜了,求轻喷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));
    }
    
  • 相关阅读:
    为什么 Redis 重启后没有正确恢复之前的内存数据
    Redis的启动过程
    Redis 如何保持和MySQL数据一致
    redis集群节点宕机
    mysql 数据库管理
    mysqladmin 命令详解
    MySQL 编译安装
    mysql 数据库简介
    xtrabackup安装部署(二)
    Non-negative Partial Sums(单调队列)
  • 原文地址:https://www.cnblogs.com/Y15BeTa/p/15704621.html
Copyright © 2011-2022 走看看