[C++]实现10以内整数的简单科学计算器
大家好!今天带来的是自己实现的用C++实现的10以内整数的科学计算器,其中涉及中缀表达式到后缀表达式(逆波兰表示法),后缀表达式的求值,涉及栈这一数据结构的压栈,弹栈,存取栈顶元素和判断栈是否为空等操作.
计算器在生活中应用广泛.众所周知,我们往计算器中输入的是由数字,运算符组成的表达式,这个表达式被称为中缀表达式,因其运算符写在数的中间,如(1+2)*3.而用栈实现的计算器所处理的是后缀表达式,即运算符在数字的后面,这涉及到中缀表达式转后缀表达式的算法.如(1+2)*3的后缀表达式是12+3*.后缀表达式也称为逆波兰表示法,因其是一种由波兰数学家扬·武卡谢维奇在1920年引入的数学表达式方式.
整个工程涉及两个编译单元,即main.cpp主函数文件和caculatefuncs.h自定义头文件.main.cpp的代码十分简单,就是读入中缀表达式,然后调用toPostFix函数,转变为后缀表达式,再调用toDouble函数将后缀表达式求值.代码如下:
1 #include <iostream> 2 #include"caculatefuncs.h" 3 4 using namespace std; 5 6 int main() 7 { 8 9 string infix; 10 11 cout << "输入中缀表达式:" << endl; 12 cin >> infix; 13 14 string postfix = toPostFix(infix); 15 cout << "对应的后缀表达式(逆波兰表示法)为" << postfix << endl; 16 cout << "表达式的值为:" << toDouble(postfix) << endl; 17 return 0; 18 }
caculatefuncs.h中包含两个函数toPostFix和toDouble的实现.中缀转后缀的算法有一点复杂,规则如下:
toPostFix函数的实现:
1 string toPostFix(const string &infix) //中缀表达式转后缀表达式函数 2 { 3 4 const int n = infix.length(); 5 const char PRI1 = '2'; 6 const char PRI2 = '1'; //优先级定义 7 const char UN = '0'; 8 string postfix( n, ' '); //预留后缀表达式字符串 9 string priority( n, ' '); //预留优先级字符串 10 int i = 0; // infix序数 11 int j = 0; //priority序数 12 int k = 0; //postfix序数 13 14 for ( ; i < n; i++) 15 { 16 if (infix.at(i) >= '0' && infix.at(i) <= '9') 17 postfix.at(k++) = infix.at(i); //数字直接存入 18 19 else 20 { 21 22 switch (infix.at(i)) 23 { 24 case '+': 25 priority.at(j++) = PRI2; 26 break; 27 28 case '-': 29 priority.at(j++) = PRI2; 30 break; 31 32 case '*': 33 priority.at(j++) = PRI1; 34 break; 35 36 case '/': 37 priority.at(j++) = PRI1; 38 break; 39 40 case '(': 41 priority.at(j++) = UN; 42 break; 43 44 case ')': 45 while (charStack.top() != '(') 46 { 47 postfix.at(k++) = charStack.top(); 48 charStack.pop(); 49 j--; 50 } 51 52 charStack.pop(); 53 j--; 54 break; 55 56 default: 57 try 58 { 59 throw runtime_error("unknown operator"); 60 } 61 catch (runtime_error err) 62 { 63 cout << err.what(); 64 exit(EXIT_FAILURE); 65 } //优先级字符串中存放代表优先级的字符常量 66 } 67 68 if ( j > 1 && priority.at(j - 1) < priority.at(j - 2) && priority.at(j - 1) != UN && priority.at(j - 2) != UN) //当前运算符优先级比栈顶运算符低,则待高优先级运算符弹栈后入栈 69 { 70 postfix.at(k++) = charStack.top(); 71 charStack.pop(); 72 charStack.push(infix.at(i)); 73 priority.at(j - 2) = priority.at(j - 1); 74 j--; 75 } 76 else if ( infix.at(i) != ')') 77 charStack.push(infix.at(i)); 78 79 if ( j > 1) 80 { 81 for ( int m = j - 2; (m >= 0) && (priority.at(m) > priority.at(j - 1)); m--) //优先级比较,高于当前运算符优先级的弹栈 82 { 83 if (priority.at(m) != UN && priority.at(j - 1) != UN ) 84 { 85 postfix.at(k++) = charStack.top(); 86 charStack.pop(); 87 j--; 88 } 89 } 90 } 91 } 92 } 93 94 while ( !charStack.empty()) //栈中字符全部弹出 95 { 96 postfix.at(k++) = charStack.top(); 97 charStack.pop(); 98 } 99 100 postfix = postfix.substr(0, k); 101 return postfix; 102 }
至于后缀表达式求值的算法,我们都比较熟悉了.遍历后缀表达式,若是操作数,则压入栈;若为运算符,则从栈中弹出两个操作数,进行计算,然后将计算结果压栈.直至遍历完成时,栈为空.
toDouble函数的实现:
1 double toDouble(const string &postfix) //逆波兰表示法转换为整数函数 2 { 3 4 const int n = postfix.length(); 5 double a = 0; //第一个操作数 6 double b = 0; //第二个操作数 7 8 for (int i = 0; i < n; i++) 9 { 10 char temp = postfix.at(i); 11 12 if (temp >= '0' && temp <= '9') //是数字则压栈 13 doubleStack.push( temp - '0'); 14 else //运算符分情况讨论 15 { 16 switch (temp) 17 { 18 case '+': 19 b = doubleStack.top(); 20 doubleStack.pop(); 21 a = doubleStack.top(); 22 doubleStack.pop(); 23 doubleStack.push(a + b); //运算结果压栈 24 break; 25 26 case '-': 27 b = doubleStack.top(); 28 doubleStack.pop(); 29 a = doubleStack.top(); 30 doubleStack.pop(); 31 doubleStack.push(a - b); 32 break; 33 34 case '*': 35 b = doubleStack.top(); 36 doubleStack.pop(); 37 a = doubleStack.top(); 38 doubleStack.pop(); 39 doubleStack.push(a * b); 40 break; 41 42 case '/': 43 try 44 { 45 b = doubleStack.top(); 46 47 if (b == 0) 48 { 49 throw runtime_error("divided 0"); 50 } 51 } 52 catch (runtime_error err) 53 { 54 cout << err.what() << endl; 55 exit(EXIT_FAILURE); 56 } 57 58 doubleStack.pop(); 59 a = doubleStack.top(); 60 doubleStack.pop(); 61 doubleStack.push(a / b); 62 break; 63 64 default: 65 try 66 { 67 throw runtime_error("unknown operator"); 68 } 69 catch (runtime_error err) 70 { 71 cout << err.what(); 72 exit(EXIT_FAILURE); 73 } 74 } 75 } 76 } 77 78 return doubleStack.top(); //最终结果弹栈 79 }
这个简单计算器实现只能处理10以内的整数,但结果可以为浮点数.可以处理括号,考虑运算符优先级.栈的是运用了C++的模板类Stack,类声明被包含在头文件stack中.本程序使用的两个栈定义如下:
stack<char> charStack; //存放字符的栈 stack<double> doubleStack; //存放整数的栈
本人原创,谢谢大家!转载请注明出处,谢谢合作!
转载于:https://www.cnblogs.com/Agent-YRBlogs/p/5987603.html
[C++]实现10以内整数的简单科学计算器相关推荐
- 计算机课设:基于Java实现的简单科学计算器
设计目的 对Java课程知识的总结,进一步提高对Java语言的理解与掌握 深入的理解Java语言,并将其中抽象概念运用到实际编程中,锻炼学生的课题分析和解决问题的能力,培养正确的编程习惯 培养自主学习 ...
- 科学计算机怎么直接显示10的多少次方,3的几次方等于10 怎么算 log及科学计算器里的其它 函数怎么正确输入...
3的几次方等于10 怎么算 log及科学计算器里的其它 函数怎么正确输入以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ...
- 小学科学作业计算器c语言,怎样用C实现一个简单科学计算器
写了两个小时写的很粗陋,只能计算整数,但是可以支持多级别括号,和同一级别的多个括号. 希望大家多多指教,这个题目其实很有意思,要是大家有兴趣,可以把功能做的更加全面,比如算次方什么的 #include ...
- 1.10 编程基础之简单排序 06 整数奇偶排序 python
http://noi.openjudge.cn/ch0110/06/ """ 1.10 编程基础之简单排序 06 整数奇偶排序 http://noi.openjudge. ...
- Scratch简单10以内加法游戏
10以内加法游戏 给小朋友做一个10以内的加法游戏,考考小朋友,超级简单的说. 首先定义三个角色 小黄鱼: 用于提出问题并根据回答判断答案是否正确 水母哥:悠哉游动,被点击时给出答案 开始标志:点击后 ...
- 写出10以内的奇偶数php,幼儿园中班科学活动“认识奇数偶数”
幼儿园中班科学活动"认识奇数偶数" 学前教育更要重视孩子良好习惯的养成.下面是小编整理的幼儿园中班科学活动"认识奇数偶数",大家一起来看看吧. 活动目标: 1. ...
- 按群计数10以内_按数群计数教案
活动目标1.学习1-20按群计数,两个两个数.2.建立数群概念.3.培养幼儿的观察力.判断力及动手操作能力.4.了解数字在日常生活中的应用,初步理解数字与人们生活的关系.5.乐意参与活动,体验成功后的 ...
- 10以内加减法编程_500字以内的面向对象编程。
10以内加减法编程 Object Oriented Programming (OOP) is all too often viewed by those unfamiliar to it as a s ...
- 10以内的分解与组成怎么教_“10以内数的组成”训练方法
"10以内数的组成"训练方法 南寨小学附属幼儿园武倍伊 现在一定有不少家长为孩子背"10以内数的组成"而发愁.烦恼呢?记忆分解和组成,是一件枯燥无味的事儿.但分 ...
- 百度的科学计算器(简单)
今年,百度的科学计算器进行了重大更新,可以计算更为复杂的表达式了. 定义表达式中存在加减运算.括号.函数调用.强制类型转换这几种运算.其中数值的类型有整型与浮点型两种.并且, 整型与整型加减运算的结果 ...
最新文章
- ACR2010_MRI骶髂关节炎症与CTX-II变化以及TNF拮抗剂治疗过程中全身炎症改变相关...
- 利用jdom生成XML文件
- cProfile——Python性能分析工具
- python中字典的find_python-re.findall返回命名捕获组的字典?
- 微服务架构下,DLI的部署和运维有何奥秘?
- CSS快速学习6:vertical-align讲解
- 【以太坊源码】以太坊黄皮书参数
- CSDN插件限时内测,新用户抢永久免费去广告特权
- 没有mysql支持时的替代方案
- [转载] 机器学习篇—Numpy数值计算基础(中)
- java脚本语言 dim_写给新手windows脚本的入门
- CommandLineToArgvW
- 易语言PHP非对称加密,openssl调用大集合[易语言源码] | 贝贝吧
- java开发职业规划
- 萤火虫小程序_线上服务不断档 萤火虫水洞·地下大峡谷推出“云旅游”新体验...
- Landsat8—ANG.txt文件
- 计算机网络教程第五版|微课版 - 第一章 概述 - 重点概念
- 第三方支付的流程分析与总结
- Android中的占位符
- 彻底搞懂MySql的B+Tree
热门文章
- 网络运维工程师技能图谱,这些你都会吗?
- mysql 延时update_转 MySQL延迟更新索引(delay_key_write)
- 串口与定时器的重要关系_单片机串口必备基础知识
- Centos7.x 装机优化
- 17995 Stupid thief 组合数学
- python程序打包成exe(使用pyinstaller)
- 知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException v2 q31无涯 - I...
- 【程序猿】2016年自己的十年计划篇
- iOS 编译后的Archiveing 界面在 Windows-organizer 下
- Android 调整控件位置和大小(以textView为例,并设置字体与背景颜色)