php利用堆栈 实现高级计算器
当我们得到一个字符串运算式该如何去得出它的运算结果呢?
这时候我们就能使用堆栈的算法很巧妙的解决这个问题。
思路是这样的:(我们利用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利用堆栈 实现高级计算器相关推荐
- PHP高级计算器的过程,PHP基于堆栈实现的高级计算器功能示例
PHP基于堆栈实现的高级计算器功能示例 发布于 2017-10-14 13:38:26 | 108 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...
- HTML中利用堆栈方式对Table进行行排序
<!-- all rights by Lonsan on 2005 email:Lonsan21@163.com --> <html> <head> < ...
- java高级计算器_高级计算器[Java版]
import java.util.Scanner; /* * time: 2012年11月17日 11:34:10 * content: 高级计算器 * author: 覃唐 ...
- 【基本办公软件】万彩办公大师教程丨高级计算器的应用
横屏显示高级计算器,含加减乘除.百分比.数值记忆储存.清除等标准计算,支持三角函数,反三角函数,指数,对数函数,幂函数,求余函数,阶乘等科学计算,实现逻辑移位指令.逻辑运算.十六进制.十进制.二进制快 ...
- 利用G25祖源计算器坐标画PCA散点图
利用G25祖源计算器坐标画PCA散点图 概述 编程语言:python3.x 模块:numpy sklearn matplotlib 可选:jupyter 整体思路:将G25给出的25维坐标降维并画图 ...
- 二叉树利用堆栈实现遍历的非递归算法
二叉树的遍历有三种不同的遍历方法,分别是前序遍历.中序遍历以及后序遍历 遍历的实现我们在上一篇博客中已经用递归的方法实现了,那么可不可以不用递归实现呢,答案是可以的 在这一篇博客中我们会利用堆栈将遍历 ...
- 干货 | 利用SPSS进行高级统计分析第一期
干货 | 利用SPSS进行高级统计分析第一期 1 描述性统计表格模板 2 两者之间有无显著差异:卡方&T检验 3 相关&回归 Hello, 这里是行上行下,我是喵君姐姐~ 你是否还在为 ...
- 基于JavaSwing的高级计算器
开发环境 eclipse+jdk1.8 系统简介 本系统是一个Java开发的高级计算器,可以实现工程计算类,以及平方根,开根号,加括号运算等等功能,具体可看演示视频,本系统无数据库! 演示视频 基于J ...
- 编译原理-如何使用flex和yacc工具构造一个高级计算器
Flex工具的使用方法 Lex 是一种生成扫描器的工具. Lex是Unix环境下非常著名的工具,主要功能是生成一个扫描器(Scanner)的C源码. 扫描器是一种识别文本中的词汇模式的程序. 这些词汇 ...
最新文章
- Ubuntu 10.10 安装 libx11-dev
- Springboot - -web应用开发-Servlets, Filters, listeners
- 【译】node js event loop part 1.1
- 电商云里 Product bundling 的一些概念
- 第4章 字符串和格式化输入/输出
- 用python自动发邮件_Python实现向QQ群成员自动发邮件的方法
- CTF基本赛制与题型
- 在命令行上启用 64 位 Visual C++ 工具集
- 【英语学习】【Level 07】U04 Rest and Relaxation L6 Your home away from home
- Angular 7和.NET Core 2.2——全球天气(第3部分)
- UnityShader33:GPU 实例化
- 隔壁桌的美女同事问我,凭啥子Nginx的并发数可以达到3w?我这次被打脸了~
- 【CS285 深度强化学习 】作业一之详解 [Deep Reinforcement Learning]
- 保利威 API设置直播回放
- SPF算法中的ISPF和PRC介绍
- kaka的使用以及理解
- 多臂赌博机Multi-Armed Bandit(MAB)
- 危夷晨:来自“AI黄埔军校”的计算机视觉创业者
- 【Spark重点难点】你从未深入理解的RDD和关键角色
- Linux 文件属性与权限