大家好!今天带来的是自己实现的用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以内整数的简单科学计算器相关推荐

  1. 计算机课设:基于Java实现的简单科学计算器

    设计目的 对Java课程知识的总结,进一步提高对Java语言的理解与掌握 深入的理解Java语言,并将其中抽象概念运用到实际编程中,锻炼学生的课题分析和解决问题的能力,培养正确的编程习惯 培养自主学习 ...

  2. 科学计算机怎么直接显示10的多少次方,3的几次方等于10 怎么算 log及科学计算器里的其它 函数怎么正确输入...

    3的几次方等于10 怎么算 log及科学计算器里的其它 函数怎么正确输入以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ...

  3. 小学科学作业计算器c语言,怎样用C实现一个简单科学计算器

    写了两个小时写的很粗陋,只能计算整数,但是可以支持多级别括号,和同一级别的多个括号. 希望大家多多指教,这个题目其实很有意思,要是大家有兴趣,可以把功能做的更加全面,比如算次方什么的 #include ...

  4. 1.10 编程基础之简单排序 06 整数奇偶排序 python

    http://noi.openjudge.cn/ch0110/06/ """ 1.10 编程基础之简单排序 06 整数奇偶排序 http://noi.openjudge. ...

  5. Scratch简单10以内加法游戏

    10以内加法游戏 给小朋友做一个10以内的加法游戏,考考小朋友,超级简单的说. 首先定义三个角色 小黄鱼: 用于提出问题并根据回答判断答案是否正确 水母哥:悠哉游动,被点击时给出答案 开始标志:点击后 ...

  6. 写出10以内的奇偶数php,幼儿园中班科学活动“认识奇数偶数”

    幼儿园中班科学活动"认识奇数偶数" 学前教育更要重视孩子良好习惯的养成.下面是小编整理的幼儿园中班科学活动"认识奇数偶数",大家一起来看看吧. 活动目标: 1. ...

  7. 按群计数10以内_按数群计数教案

    活动目标1.学习1-20按群计数,两个两个数.2.建立数群概念.3.培养幼儿的观察力.判断力及动手操作能力.4.了解数字在日常生活中的应用,初步理解数字与人们生活的关系.5.乐意参与活动,体验成功后的 ...

  8. 10以内加减法编程_500字以内的面向对象编程。

    10以内加减法编程 Object Oriented Programming (OOP) is all too often viewed by those unfamiliar to it as a s ...

  9. 10以内的分解与组成怎么教_“10以内数的组成”训练方法

    "10以内数的组成"训练方法 南寨小学附属幼儿园武倍伊 现在一定有不少家长为孩子背"10以内数的组成"而发愁.烦恼呢?记忆分解和组成,是一件枯燥无味的事儿.但分 ...

  10. 百度的科学计算器(简单)

    今年,百度的科学计算器进行了重大更新,可以计算更为复杂的表达式了. 定义表达式中存在加减运算.括号.函数调用.强制类型转换这几种运算.其中数值的类型有整型与浮点型两种.并且, 整型与整型加减运算的结果 ...

最新文章

  1. ACR2010_MRI骶髂关节炎症与CTX-II变化以及TNF拮抗剂治疗过程中全身炎症改变相关...
  2. 利用jdom生成XML文件
  3. cProfile——Python性能分析工具
  4. python中字典的find_python-re.findall返回命名捕获组的字典?
  5. 微服务架构下,DLI的部署和运维有何奥秘?
  6. CSS快速学习6:vertical-align讲解
  7. 【以太坊源码】以太坊黄皮书参数
  8. CSDN插件限时内测,新用户抢永久免费去广告特权
  9. 没有mysql支持时的替代方案
  10. [转载] 机器学习篇—Numpy数值计算基础(中)
  11. java脚本语言 dim_写给新手windows脚本的入门
  12. CommandLineToArgvW
  13. 易语言PHP非对称加密,openssl调用大集合[易语言源码] | 贝贝吧
  14. java开发职业规划
  15. 萤火虫小程序_线上服务不断档 萤火虫水洞·地下大峡谷推出“云旅游”新体验...
  16. Landsat8—ANG.txt文件
  17. 计算机网络教程第五版|微课版 - 第一章 概述 - 重点概念
  18. 第三方支付的流程分析与总结
  19. Android中的占位符
  20. 彻底搞懂MySql的B+Tree

热门文章

  1. 网络运维工程师技能图谱,这些你都会吗?
  2. mysql 延时update_转 MySQL延迟更新索引(delay_key_write)
  3. 串口与定时器的重要关系_单片机串口必备基础知识
  4. Centos7.x 装机优化
  5. 17995 Stupid thief 组合数学
  6. python程序打包成exe(使用pyinstaller)
  7. 知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I...
  8. 【程序猿】2016年自己的十年计划篇
  9. iOS 编译后的Archiveing 界面在 Windows-organizer 下
  10. Android 调整控件位置和大小(以textView为例,并设置字体与背景颜色)