当我们得到一个字符串运算式该如何去得出它的运算结果呢?

这时候我们就能使用堆栈的算法很巧妙的解决这个问题。

思路是这样的:(我们利用php函数substr循环去截取这个字符串运算式,依次取出这个字符串的值【我们得从第一个字符开始截取】,我们将开始截取位置设为一个循环增长的变量,初始化为【$index=0】),同时还需要创建两个栈,一个专门存放数字【$numStack】,一个存放运算符【$operStack】,我们还需要一个可以判断是否是运算符号的函数,将每次截取的值放入这个自定义函数中,返回一个可以区别为数字或运算符的标识,通过对这个标识的判断确定值是数字还是运算符,是数字就插入数栈,是运算符的话就插入符号栈。插入数栈的话可直接插入,但是符号栈的话需要特殊处理一下[【如果符号栈为空则直接插入,不为空:我们要将插入的符号与栈内的符号进行运算优先级比较(可以定义一个函数来判定符号优先级,把 *  和 / 假定为1  把 + 和 - 假定为0  假设数字大的优先级高,如此就能得出运算符优先级),当待插入的符号优先级小于等于栈内顶端的运算符优先级,就从数栈弹出两个值  符号栈弹出一个运算符 将它们进行运算】

下面是一个php的实例【参考自韩顺平老师的php算法教程】

<html>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8'/>
</head>
<h1>高级计算器</h1>
<?php
/*** 一个栈类*/
class MyStack{public $top=-1;//默认是-1,表示该栈是空的public $maxSize=15;//$maxSize表示栈最大容量public $stack=array();////入栈的操作public function  push($val){//先判断栈是否已经满了if($this->top==$this->maxSize-1){echo '<br/>栈满,不能添加';return;}$this->top++;$this->stack[$this->top]=$val;}//出栈的操作,就是把栈顶的值取出public function pop(){//判断是否栈空if($this->top==-1){echo '<br/>栈空1';return;}//把栈顶的值,取出$topVal=$this->stack[$this->top];$this->top--;return $topVal;}//显示栈的所有数据的方法.public function showStack(){if($this->top==-1){echo '<br/>栈空2';return;}echo '<br/>当前栈的情况是....';for($i=$this->top;$i>-1;$i--){echo '<br/> stack['.$i.']='.$this->stack[$i];}}//判断是否是一个运算符public function isOper($val){if ($val=='+'||$val=='-'||$val=='*'||$val=='/'){return true;}}//判断栈是否为空public function isEmpty(){if ($this->top==-1) return true;}/*** 比较运算符的优先级* 我把 * 和/运算符的优先级看作1* +和- 看作0* 通过它们之间的比较就能得出它们的优先级谁更高*/public function PRI($oper){if ($oper=='*'||$oper=='/'){return 1;} else if ($oper=='+'||$oper=='-') {return 0;}}//返回栈顶端的值public function getTop(){return $this->stack[$this->top];}//计算public function getResult($num1,$num2,$oper){switch ($oper){case '+':$res = $num2+$num1;break;case '-':$res = $num2-$num1;break;case '*':$res = $num2*$num1;break;case '/':$res = $num2/$num1;break;}return $res;}}//需要进行运算的表达式$str = '12+5*2+3-5*2';//字符串的指针$index = 0;//声明一个用于组合联系数字的变量$keepNum = '';//定义一个数栈和一个符号栈$numsStack=new MyStack();$operStack=new MyStack();while (true){$val = mb_substr($str,$index,1);//如果是一个符号就入符号栈 否则入数栈if ($operStack->isOper($val)==true){//符号入栈前需要判断一下 栈为空直接入栈 不为空需要比较当前运算符与栈顶端的运算符//如果当前运算符的优先级低于栈内的 则需要运算if ($operStack->isEmpty()){$operStack->push($val);} else {while (!$operStack->isEmpty()&&$operStack->PRI($val)<=$operStack->PRI($operStack->getTop())){//当前符号的优先级要直到高于栈内的时候才能入栈 否则要计算//当前运算符的优先级低于栈内的 则运算$num1 = $numsStack->pop();$num2 = $numsStack->pop();$oper = $operStack->pop();$res  = $numsStack->getResult($num1,$num2,$oper);//计算完毕将结果入栈$numsStack->push($res);}//把当前这个符号再入符号栈$operStack->push($val);    }} else {//考虑如果是连续数字的问题$keepNum.=$val;//先判断是否已经到字符串最后.如果已经到最后,就直接入栈.if ($index==mb_strlen($str)-1){$numsStack->push($keepNum);//是数字直接入栈} else {//要判断一下$ch字符的下一个字符是数字还是符号.if ($operStack->isOper(mb_substr($str,$index+1,1))){$numsStack->push($keepNum);$keepNum='';}}}$index++;//让$index指向下一个字符.if ($index==mb_strlen($str)) break;//已扫描到字符串的末尾 就退出while循环}/*4. 当扫描完毕后,就依次弹出数栈和符号栈的数据,并计算,最终留在数栈的值,就是运算结果,只有符号栈不空就一直计算*/while (!$operStack->isEmpty()){$num1 = $numsStack->pop();$num2 = $numsStack->pop();$oper = $operStack->pop();$res  = $numsStack->getResult($num1,$num2,$oper);//计算完毕将结果入栈$numsStack->push($res);}//当退出while后,在数栈一定有一个数,这个数就是最后结果
echo $str.'='.$numsStack->getTop();?>

php利用堆栈 实现高级计算器相关推荐

  1. PHP高级计算器的过程,PHP基于堆栈实现的高级计算器功能示例

    PHP基于堆栈实现的高级计算器功能示例 发布于 2017-10-14 13:38:26 | 108 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...

  2. HTML中利用堆栈方式对Table进行行排序

    <!--   all rights by Lonsan on 2005  email:Lonsan21@163.com --> <html> <head> < ...

  3. java高级计算器_高级计算器[Java版]

    import java.util.Scanner; /* * time:       2012年11月17日 11:34:10 * content:     高级计算器 * author:    覃唐 ...

  4. 【基本办公软件】万彩办公大师教程丨高级计算器的应用

    横屏显示高级计算器,含加减乘除.百分比.数值记忆储存.清除等标准计算,支持三角函数,反三角函数,指数,对数函数,幂函数,求余函数,阶乘等科学计算,实现逻辑移位指令.逻辑运算.十六进制.十进制.二进制快 ...

  5. 利用G25祖源计算器坐标画PCA散点图

    利用G25祖源计算器坐标画PCA散点图 概述 编程语言:python3.x 模块:numpy sklearn matplotlib 可选:jupyter 整体思路:将G25给出的25维坐标降维并画图 ...

  6. 二叉树利用堆栈实现遍历的非递归算法

    二叉树的遍历有三种不同的遍历方法,分别是前序遍历.中序遍历以及后序遍历 遍历的实现我们在上一篇博客中已经用递归的方法实现了,那么可不可以不用递归实现呢,答案是可以的 在这一篇博客中我们会利用堆栈将遍历 ...

  7. 干货 | 利用SPSS进行高级统计分析第一期

    干货 | 利用SPSS进行高级统计分析第一期 1 描述性统计表格模板 2 两者之间有无显著差异:卡方&T检验 3 相关&回归 Hello, 这里是行上行下,我是喵君姐姐~ 你是否还在为 ...

  8. 基于JavaSwing的高级计算器

    开发环境 eclipse+jdk1.8 系统简介 本系统是一个Java开发的高级计算器,可以实现工程计算类,以及平方根,开根号,加括号运算等等功能,具体可看演示视频,本系统无数据库! 演示视频 基于J ...

  9. 编译原理-如何使用flex和yacc工具构造一个高级计算器

    Flex工具的使用方法 Lex 是一种生成扫描器的工具. Lex是Unix环境下非常著名的工具,主要功能是生成一个扫描器(Scanner)的C源码. 扫描器是一种识别文本中的词汇模式的程序. 这些词汇 ...

最新文章

  1. Ubuntu 10.10 安装 libx11-dev
  2. Springboot - -web应用开发-Servlets, Filters, listeners
  3. 【译】node js event loop part 1.1
  4. 电商云里 Product bundling 的一些概念
  5. 第4章 字符串和格式化输入/输出
  6. 用python自动发邮件_Python实现向QQ群成员自动发邮件的方法
  7. CTF基本赛制与题型
  8. 在命令行上启用 64 位 Visual C++ 工具集
  9. 【英语学习】【Level 07】U04 Rest and Relaxation L6 Your home away from home
  10. Angular 7和.NET Core 2.2——全球天气(第3部分)
  11. UnityShader33:GPU 实例化
  12. 隔壁桌的美女同事问我,凭啥子Nginx的并发数可以达到3w?我这次被打脸了~
  13. 【CS285 深度强化学习 】作业一之详解 [Deep Reinforcement Learning]
  14. 保利威 API设置直播回放
  15. SPF算法中的ISPF和PRC介绍
  16. kaka的使用以及理解
  17. 多臂赌博机Multi-Armed Bandit(MAB)
  18. 危夷晨:来自“AI黄埔军校”的计算机视觉创业者
  19. 【Spark重点难点】你从未深入理解的RDD和关键角色
  20. Linux 文件属性与权限

热门文章

  1. js 读取图片路径并预览图片
  2. 基于FPGA的UART串口通信实验(VHDL语言实现)
  3. 什么是相位,为什么会有相位?
  4. 初识Java+JDK的安装与环境变量的配置+IDEA的安装
  5. 带你了解IT互联网行业程序员岗位有些什么类型?
  6. 易点易动助力企业固定资产信息化管理
  7. 文本修饰标签(text-decoration)
  8. ChatGPT助力之论文速成秘籍
  9. 使用EasyPoi导出Word文件,使用@Excel注释导出实体对象图片的解决方案
  10. 全球首份AR报告第二章:AR的工作原理