计算器之逆波兰算法
2014-05-02 01:10
169 查看
// // main.c // 我来教你学数学(小学版) // // Created by 颜风 on 14-4-25. // Copyright (c) 2014年 天启. All rights reserved. // #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include<math.h> #include <string.h> #define LIMIT 200 //允许的字符串表达式的最大长度 //----------------函数声明-------------- /**计算器 */ void calculator(); // ---------------------------------- /*中缀转后缀 * *@expr char* 一个数学表达式的字符串形式,同时用于接收生成的后缀表达式. */ void _trans(char* expr); // --------------------------------- /*计算后缀表达式的结果 * *@rpn char* 一个后缀表达式. *@return double 返回计算结果. */ double _calculate(char* rpn); //---------------函数定义--------------- /**计算器 */ void calculator() { //欢迎界面 printf("********************************\n"); printf("=======我来教你学数学(小学版)======\n"); printf("********************************\n"); //计算 for (int select = 1; select == 1; ) { char expr[LIMIT] = {0}; printf("请您输入任一数学四则表达式\n"); printf(">>:"); scanf("%s", expr); printf("\n"); //使用新的数组存储expr,以便于将中缀表达式转换为后缀表达式 char rpn[LIMIT] = {0}; //for (char *ch = expr, *top = rpn; *ch != '\0' && top != rpn+LIMIT-1; *top++ = *ch++); for(int i = 0; i < LIMIT; i++) rpn[i] = expr[i]; //中缀转后缀 _trans(rpn); //计算并返回表达式的值. //return _calculate(rpn); printf("\n综上所述:\t%s = %g\n", expr, _calculate(rpn)); printf("\n是否继续?1.继续 2.退出\n"); printf(">>:"); scanf("%d", &select); printf("\n"); } //结束界面 printf("谢谢使用,祝您生活愉快!O(∩_∩)O~~\n"); } //------------------------------------ /*中缀转后缀 *@expr char* 一个数学表达式的字符串形式,同时用于接收生成的后缀表达式. */ void _trans(char* expr) { char end = '#';//字符串表达式的结束符. expr[strlen(expr)] = end;//为表达式添加结束符. char result[LIMIT] = {0}; char* top = result;//用于存储波兰表达式的栈的头指针 //定义一个栈,临时存储操作符 char temp_stack[LIMIT] = {0}; temp_stack[0] = end;//使用 # 作为字符表达式结束的标识符. char* top_temp = &temp_stack[1];//临时栈的头指针 //逆波兰算法 for (char* p_expr = &expr[0]; *p_expr != '#'; p_expr++) { switch(*p_expr) { case '(': /*判定为左括号*/ *top_temp++ = *p_expr; break; case ')': /*判定为右括号*/ for (; *(top_temp-1) != '('; *top++ = *--top_temp); *--top_temp = '\0';//舍弃'(' break; case '+': /*判定为加减号*/ case '-': for (; *(top_temp-1) != end && *(top_temp-1) != '('; *top++ = *--top_temp); *top_temp++ = *p_expr; break; case '*': /*判定为乘除号*/ case '/': for (; *(top_temp-1) == '*'|| *(top_temp-1) == '/'; *top++ = *--top_temp); *top_temp++ = *p_expr; break; case ' ': break; default: for (; (*p_expr >= '0' && *p_expr <= '9') || *p_expr == '.'; *top++ = *p_expr++); p_expr--; *top++ = ' '; } } for (; *(top_temp-1) != end; *top++ = *--top_temp); //使用expr接收后缀表达式 for (char *e = expr; *e != '\0'; *e++ = '\0'); //重置expr. for(char *e = expr, *r = result; *r != '\0'; *e++ = *r++); } // ---------------------------------- /*计算后缀表达式的结果 * *@rpn char* 一个后缀表达式. *@return double 返回计算结果. */ double _calculate(char* rpn) { double stack[LIMIT] = {0}; // 作为栈使用 double* top = stack;// 作为栈的头指针使用 int step = 0;//第几步运算 printf("您可以按以下步骤计算:\n"); for (char* ch = rpn; *ch != '\0'; ch++) { switch(*ch) { case '+': printf("第 %d 步:\t%g %c %g = %g\n", ++step, *(top-2), *ch, *(top-1), *(top-2) + *(top-1)); *(top-2) = *(top-2) + *(top-1); top--; break; case '-': printf("第 %d 步:\t%g %c %g = %g\n", ++step, *(top-2), *ch, *(top-1), *(top-2) - *(top-1)); *(top-2) = *(top-2) - *(top-1); top--; break; case '*': printf("第 %d 步:\t%g %c %g = %g\n", ++step, *(top-2), *ch, *(top-1), *(top-2) * *(top-1)); *(top-2) = *(top-2) * *(top-1); top--; break; case '/': if(*(top-1) == 0) { printf("第 %d 步:\t%g %c %g = ?\t错误!零不能做除数!\n", ++step, *(top-2), *ch, *(top-1)); exit(0); /*异常退出*/ } printf("第 %d 步:\t%g %c %g = %g\n", ++step, *(top-2), *ch, *(top-1), *(top-2) / *(top-1)); *(top-2) = *(top-2) / *(top-1); top--; break; case ' ': break; default: *top++= atof(ch); for (; *ch != ' '; ch++); break; } } return stack[0]; } int main(int argc, const char * argv[]) { calculator(); return 0; }
相关文章推荐
- 基于逆波兰RPN算法的计算器实现
- 逆波兰算法,实现一个四则运算计算器
- 栈和队列5|逆波兰计算器 - 数据结构和算法27
- 栈和队列5|逆波兰计算器 - 数据结构和算法27
- 逆波兰计算器
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 算法基础系列之四:表达式计算及逆波兰栈
- 如何用程序实现逆波兰表达式值算法问题
- 简易计算器(逆波兰算法)
- 调度场算法与逆波兰表达式
- 51单片机:利用定时器中断写一个简易加法计算器,按键消抖算法很好。
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 逆波兰算法(多位数运算)
- vb.net 逆波兰算法
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 逆波兰表达式的转化算法
- 算法--逆波兰式(后缀式)
- 算法爱好者——逆波兰表达式 ? 待解决
- 算法-波兰表达式求值(递归)