写在前面的话:本专栏的主要内容:数据结构与算法。

1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己构建的,未使用系统的库文件,因此,建议这类小伙伴们从本专栏的总揽​​​​​​​按顺序进行学习;

​​​​​​​2.对于想查询有关资料的小伙伴们,可以选择性地浏览。希望小伙伴们都能有所收获~

​  ​​​​​​】

本章为栈的第三个应用:

问题描述:如何计算一个字符串表达式的值?

咱也可以从另一个角度来认识这个问题:

------如何制作一个简易的计算器?

实际上,要想实现一个计算器的功能,是一个非常复杂的问题,

下面我们将问题简化一下,假设此表达式中,

运算符只有:“+”,“-”,“*”,“/”,阶乘,方幂这六种再加上括号,

于是,我们有以下的栈结构实现(EvaluAlgor.h):

本质来说,该算法并不算完善,读者可以思考一下,该算法中存在什么问题?


/** 作者:易果啥笔* 时间:2021.8.20* 内容:栈的典型应用三:求一个字符串表达式的数值**/#ifndef STACK_EVALUALGOR_H
#define STACK_EVALUALGOR_H
#define N_OPTR 9 //运算符总数
#include "Stack.h"
#include <cmath>
#include "ParenMatch.h"typedef enum {ADD,SUB,MUL,DIV,POW,FAC,L_P,R_P,EOE} Operator;//将运算符与上述枚举对应
Operator optrRank(char optr){switch (optr) {case '+' : return ADD;case '-' : return SUB;case '*' : return MUL;case '/' : return DIV;case '^' : return POW;case '!' : return FAC;case '(' : return L_P;case ')' : return R_P;case '\0' : return EOE;default: exit(-1);}
}//pri[]数组用于描述不同运算符之间的优先级关系
const char pri[N_OPTR][N_OPTR] = {'>','>','<','<','<','<','<','>','>','>','>','<','<','<','<','<','>','>','>','>','>','>','<','<','<','>','>','>','>','>','>','<','<','<','>','>','>','>','>','>','>','<','<','>','>','>','>','>','>','>','>',' ','>','>','<','<','<','<','<','<','<','=',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','<','<','<','<','<','<','<',' ','=',
};//readNumber()用于获取从某数字字符开始的完整一个数void readNumber(char*& S,Stack<float>& p){p.push((float)(*S-'0'));while(isdigit(*(++S)))p.push(p.pop()*10+(*S-'0')); //整数部分,注意到 '123' - '0' = 123if('.' != *S) return;float xiaoshu = 1;while(isdigit(*(++S)))p.push(p.pop()+(*S-'0')*(xiaoshu/=10)); //小数部分
}//orderBetween()用于判定操作符之间的优先级关系
char orderBetween(char optr1,char optr2){return pri[optrRank(optr1)][optrRank(optr2)]; //直接比较
}//calcu()函数用于求一个(阶乘)或两个数的运算//先求阶乘
int factorial(int n){if(n<0)exit(-1);else if(n == 1) return 1;else return n*factorial(n-1); //递归实现
}int calcu(char optr,int pOpnd){return factorial(pOpnd); }//重载calcu()方法使之适用于两个数之间的运算float calcu(float pOpnd1,char optr,float pOpnd2) {if (optr == '/' && pOpnd2 == 0) exit(-1); //除数不能为零switch (optr) {case '+' :return pOpnd1 + pOpnd2;break;case '-' :return pOpnd1 - pOpnd2;break;case '*' :return pOpnd1 * pOpnd2;break;case '/' :return pOpnd1 / pOpnd2;break;case '^' :return pow(pOpnd1, pOpnd2); //借用cmath库中的求幂函数pow()default:exit(-1);}
}//evaluate()为求值核心算法float evaluate(char *S) {if( ! paren(S,0,length(S)) ) exit(-1); //不匹配时else{Stack<float> opnd;Stack<char> optr; //运算符栈,操作符栈optr.push('\0');while (!optr.Empty()) {if (isdigit(*S)) {readNumber(S, opnd);} elseswitch (orderBetween(optr.top(), *S)) {case '<':optr.push(*S);S++;break;case '=':optr.pop();S++;break;case '>':char op = optr.pop();if ('!' == op) {float pOpnd = opnd.pop();if ((int) pOpnd == pOpnd) {opnd.push(calcu(op, (int) pOpnd));} else exit(-1); //小数没有阶乘} else {float pOpnd2 = opnd.pop(), pOpnd1 = opnd.pop();opnd.push(calcu(pOpnd1, op, pOpnd2));}break;}}return opnd.pop();}}#endif //STACK_EVALUALGOR_H

在evaluate()数值求解算法中,先使用了Paren()方法验证括号是否匹配。Paren()方法参考我的上一篇博文。此外,请读者细细体会栈在这种算法中所起的作用。

在main.cpp文件中我们可以验证它的正确性:


/** 作者:易果啥笔* 时间:2021.8.20* 内容:栈的应用**/#include <iostream>
#include "Stack.h"
#include "ParenMatch.h"
#include "EvaluAlgor.h"using namespace std;//遍历函数print
template <typename T> void print(T& e){ cout<<e; };int main() {//应用三:求一个字符串表达式的值char expression2[40] = "10^3+23/2-(56*7)+5!";cout<<"10^3+23/2-(56*7)+5!表达式的值为:"<<evaluate(expression2)<<"  "<<(10*10*10+23/2.0-(56*7)+5*4*3*2*1)<<endl;return 0;
}

仔细思考,你可以发现,这个算法是不支持负数参与计算的,这也是我前文所说的问题所在。读者可以思考一下,如何修改代码,使之支持负数参与运算。

欲了解栈的其他应用,点击传送门跳转:

1.  栈的应用(一)

2. 栈的应用(二)​​​​​​​

下一章:数据结构与算法之-----队列​​​​​​​

数据结构与算法之-----栈的应用(三)相关推荐

  1. 数据结构与算法之栈入门题目

    数据结构与算法之栈题目 目录 用数组实现大小固定的队列和栈 实现一个特殊的栈,在实现栈的基础功能上,再实现返回栈中最小元素的操作 如果仅用栈结构实现队列结构和如何仅用队列结构实现栈结构 1. 用数组实 ...

  2. 数据结构与算法--简单栈实现及其应用

    栈 栈(Stack)是一种限制插入和删除只能在一个位置上进行的表,改位置是表的末端,叫做栈顶top.栈的基本操作有push (进栈)pop(出栈) 栈又叫做LIFO(后进先出)表,下图展示普通push ...

  3. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  4. 数据结构与算法--利用栈实现队列

    利用栈实现队列 上一节中说明了栈的特点 后进先出,我们用数组的方式实现了栈的基本操作api,因此我们对栈的操作是不考虑排序的,每个api的操作基本都是O(1)的世界,因为不考虑顺序,所以找最大,最小值 ...

  5. 数据结构与算法(Python)第三天

    数据结构与算法(Python)第三天 3:链表 为什么需要链表 链表的定义 3.1 单向链表 Python 中赋值的实际意义: 节点实现 单链表的操作 单链表的实现 测试 链表与顺序表的对比 3:链表 ...

  6. 新星计划Day7【数据结构与算法】 栈Part1

    新星计划Day7[数据结构与算法] 栈Part1

  7. 数据结构与算法(2)——栈和队列

    前言:题图无关,只是好看,接下来就来复习一下栈和队列的相关知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 栈 什么 ...

  8. 【数据结构与算法】栈与队列

    栈 一.什么是栈? 1.后进者先出,先进者后出,这就是典型的"栈"结构. 2.从栈的操作特性来看,是一种"操作受限"的线性表,只允许在端插入和删除数据. 二.为 ...

  9. 数据结构与算法之-----栈的应用(二)

    [ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己 ...

最新文章

  1. AI4U:以用户友好为目标,智源重大研究方向“机器学习”学者候选人发布
  2. classification_report进阶:针对top-k的结果计算precision@k、recall@k、f1-score@k
  3. 芬兰计算机研究生申请表,芬兰的研究生申请技巧
  4. bccomp在php中什么意思,PHP bccomp()用法及代码示例
  5. TensorFlow Serving + Docker + Tornado机器学习模型生产级快速部署
  6. Java单层循环实现输出九九乘法表
  7. SAP FSM 学习笔记(二) : SAP FSM的微信接入
  8. php_os用法,golang中os包用法
  9. 小动画制作 图片盒子配合定时器 winform 114869633
  10. 向服务器上传本地大文件的方法xshell
  11. 36.5. height / width
  12. linux iconv命令详解,iconv命令
  13. cad导出pdf_CAD如何导出高分辨率图片
  14. ffmpeg php 使用教程_php的ffmpeg - CSDN博客
  15. csm和uefi_【一点资讯】关于CSM和UEFI你要知道的一些事 www.yidianzixun.com
  16. MySQL技术:数据库逻辑结构单元
  17. 前端基础——html5新增标签
  18. 湘潭大学计算机分数线,湘潭大学录取分数线2021是多少分(附历年录取分数线)
  19. android高德地图上加自定义菜单,自定义UI控件-UI界面定制-开发指南-Android 导航SDK | 高德地图API...
  20. matlab求解微分方程解析解

热门文章

  1. 一位小创业者血泪史:培养过很多技术大佬,但我还在发传单(转)
  2. canvas绘图粒子扩散效果【原创】
  3. 为什么VS提示SurfFeatureDetector不是cv的成员函数
  4. WinForm DataGridView 中的小bug.
  5. SQL SERVER 2008传递表值参数
  6. Oracle技巧集锦
  7. Shell 双引号和单引号的区别
  8. 网易2016游戏技术岗在线编程题(一)
  9. SP104 Highways (矩阵树,高斯消元)
  10. Oracle hint手动优化