前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >PHP基于堆栈实现的高级计算器功能示例

PHP基于堆栈实现的高级计算器功能示例

作者头像
用户2323866
修改于 2021-07-07 02:21:18
修改于 2021-07-07 02:21:18
5680
举报
文章被收录于专栏:技术派技术派

本文实例讲述了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=/**【要记得博客地址www.isres.com】**/15;//$maxSize表示栈最大容量 public $stack=array();// //入栈的操作 public function push($val) { //先判断栈是否已经满了 if($this-&gt;top==$this->maxSize-1){ echo '<br/>栈满,不能添加'; return; } $this->top++; $this-&gt;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&gt;-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-&gt;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+52+3-52'; //字符串的指针 $index = 0; //声明一个用于组合联系数字的变量 $keepNum = ''; //定义一个数栈和一个符号栈 $numsStack=new MyStack(); $operStack=new MyStack(); while (true) { $val = mb_substr($str,$index,1); //如果是一个符号就入符号栈 否则入数栈 if ($operStack-&gt;isOper($val)==true) { //符号入栈前需要判断一下 栈为空直接入栈 不为空需要比较当前运算符与栈顶端的运算符 //如果当前运算符的优先级低于栈内的 则需要运算 if ($operStack->isEmpty()) { $operStack-&gt;push($val); } else { while (!$operStack-&gt;isEmpty()&amp;&amp;$operStack->PRI($val)&lt;=$operStack->PRI($operStack->getTop())) { //当前符号的优先级要直到高于栈内的时候才能入栈 否则要计算 //当前运算符的优先级低于栈内的 则运算 $num1 = $numsStack->pop(); $num2 = $numsStack->pop(); $oper = $operStack->pop(); $res = $numsStack->getResult($num1,$num2,$oper); //计算完毕将结果入栈 $numsStack-&gt;push($res); } //把当前这个符号再入符号栈 $operStack-&gt;push($val); } } else { //考虑如果是连续数字的问题 $keepNum.=$val; //先判断是否已经到字符串最后.如果已经到最后,就直接入栈. if ($index==mb_strlen($str)-1) { $numsStack-&gt;push($keepNum);//是数字直接入栈 } else { //要判断一下$ch字符的下一个字符是数字还是符号. if ($operStack-&gt;isOper(mb_substr($str,$index+1,1))) { $numsStack-&gt;push($keepNum); $keepNum=''; } } } $index++;//让$index指向下一个字符. if ($index==mb_strlen($str)) break;//已扫描到字符串的末尾 就退出while循环 } /*

  1. 当扫描完毕后,就依次弹出数栈和符号栈的数据,并计算,最终留在数栈的值,就是运算结果,只有符号栈不空就一直计算 */

while (!$operStack->isEmpty()) { $num1 = $numsStack->pop(); $num2 = $numsStack->pop(); $oper = $operStack->pop(); $res = $numsStack->getResult($num1,$num2,$oper); //计算完毕将结果入栈 $numsStack-&gt;push($res); } //【一个开发人员,能懂服务器量好,反之一个服务器维护人员,也应该懂开发】//当退出while后,在数栈一定有一个数,这个数就是最后结果 echo $str.'='.$numsStack->getTop(); ?>

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
用栈来实现简易版中缀表达式的计算器
5.栈的使用场景: 1.递归 2.方法调用 3.表达式的转化和求值 4.二叉树遍历 5.图的深度优先遍历 6.逆序输出 如 单链表的反转
shengjk1
2020/02/20
4500
利用栈实现中缀表达式计算
本题看似简单,实则不然,要实现这个功能我们不能简单的直接将这个字符串丢给程序 如下
切图仔
2022/09/14
5550
利用栈实现中缀表达式计算
栈实现综合计算器
/** * 实现思路: * 1. 提前创建一个数栈和一个符号栈,分别存储数字和计算符号 * 2. 遍历计算表达式 创建一个变量存储每次遍历得到的值 * 3. 如果遍历得到的是数字,直接入数栈 * 4. 如果得到的是符号,和符号栈里的栈顶比较,如果是<=的关系 * 取出符号栈的栈顶,用一个变量存储,再取出数栈里2个数字 * 计算出结果用一个变量存储,并将结果入数栈;如果是>的关系,直接入符号栈 * 5. 当表达式扫描完毕,按照就顺序的从数栈和符号栈中取出相应的数字和符号计算,每次将结果入数栈 *
桑鱼
2020/03/18
7860
栈的数据结构
请问: 计算机底层是如何运算得到结果的? 注意不是简单的把算式列出运算,因为我们能直接看出这个算式,但是计算机怎么理解这个算式的(对计算机而言,它接收到的就是一个字符串),我们讨论的就是这个问题 -> 栈
乐心湖
2021/01/18
7080
栈的数据结构
数据结构之栈
后缀表达式适合计算式进行运算,但是人却不太容易写出来,尤其是表达式很长的情况下,因此在开发中,我们需要将中缀表达式转成后缀表达式。
用户11332765
2024/10/28
790
数据结构之栈
# 栈 栈的一个实际需求 栈的介绍 栈的应用场景 代码实现 栈实现综合计算器 # 栈的一个实际需求 请输入一个表达式 计算式:[722-5+1-5+3-3]点击计算【如下图】 请问:计算机底层是如何
用户9615083
2022/12/30
4320
栈
图解java数据结构之栈(Stack),你确定不看看吗?
1)子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
慕容千语
2021/01/05
1.2K0
图解java数据结构之栈(Stack),你确定不看看吗?
【Java数据结构和算法】008-栈
请输入一个表达式 计算式:[7*2*2-5+1-5+3-3] 点击计算【如下图】:
訾博ZiBo
2025/01/06
800
【Java数据结构和算法】008-栈
java数据结构和算法(二)
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
shaoshaossm
2022/12/26
3560
java数据结构和算法(二)
【数据结构】计算机底层是用什么识别算数表达式的?
请问: 计算机底层是如何运算得到结果的? 注意不是简单的把算式列出运算,因为我们看这个算式 7 * 2 * 2 - 5, 但是计算机怎么理解这个算式的(对计算机而言,它接收到的就是一个字符串),我们讨论的是这个问题。----> 栈
冷环渊
2021/12/29
3450
【数据结构】计算机底层是用什么识别算数表达式的?
[数据结构与算法] 邂逅栈
栈的英文为(stack): 又名堆栈,它是一种运算受限的线性表。限定仅在表尾(栈顶)进行插入和删除操作的线性表
时间静止不是简史
2020/07/25
4600
golang数据结构之利用栈求计算表达式(加减乘除)
例如:3+2*6-2 先定义两个栈,一个为数值栈,一个为运算符栈; stack.go package stack import ( "errors" "fmt" ) type Stack struct { MaxTop int //栈最大可以存放的数量 Top int //栈顶 Arr [20]int //模拟栈 } func (s *Stack) Push(val int) (err error) { //先判断栈是否满了
西西嘛呦
2020/08/26
8110
表达式求值问题
   最近在学习表达式求值问题,想使用C++或C语言实现一个带圆括号的十进制正整数的表达式求值控制台程序。这个问题可以通过栈或者二叉树遍历来解决。记得以前在学校学习数据结构中栈的应用时看到过,另外编译原理这门课也有讲过。重新翻开<<数据结构-C语言描述 耿国华 主编>>一书的P80~P83第3张有关栈相应的章节时,有一个无括号算术表达式的求值问题,其次在对应的光盘上课程设计里头有表达式求值的相关描述,这里记录如下:
ccf19881030
2019/04/24
1.3K0
【Java数据结构和算法】009-栈:前缀、中缀、后缀表达式(逆波兰表达式)
①前缀表达式(波兰表达式):前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前;
訾博ZiBo
2025/01/06
1630
数据结构【Golang实现】(五)——栈
一个表达式包含两个部分,数字和运算符。我们用两个栈来实现表达式求值,一个栈用来存储数字,一个栈用来存储运算符。
传说之下的花儿
2023/04/16
1750
C++ 使用栈求解中缀、后缀表达式的值
表达式求值对于有知识经验的人类而言,可以通过认知,按运算符的优先级进行先后运算。但对计算机而言,表达式仅是一串普通的信息而已,需要通过编码的方式告诉计算机运算法则。这个过程则需要借助于栈来实现。
一枚大果壳
2022/12/20
8880
C++ 使用栈求解中缀、后缀表达式的值
有没有想过计算机是如何处理表达式的?
https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/
代码随想录
2021/07/16
6480
C#堆栈和队列
此前已经采用 Array类和ArrayList类来把数据像列表一样组织在一起. 尽管这两种数据结构可以方便的把数据组织起来进行处理, 但是它们都没有为设计和实现实际问题的解决方案提供真正的抽象。 堆栈(stack)和队列(queue)是两种面向列表(list-oriented)的数据结构, 它们都提供了易于理解的抽象. 堆栈中的数据只能在表的某一端进行添加和删除操作, 反之队列中的数据则在表的一端进行添加操作而在表的另一端进行删除操作. 堆栈被广泛用于从表达式计算到处理方法调用的任何编程语言的实现中. 而队列则用在区分优先次序的操作系统处理以及模拟现实世界的事件方面, 比如银行出纳柜台的队列, 以及建筑物内电梯的操作。 C#为使用这些数据结构提供了两种类:Stack 类和Queue类. 本章将会讨论如何使用这些类并且介绍一些实用的例子。
苏州程序大白
2021/08/13
1.2K0
C#堆栈和队列
利用栈实现一个简易的计算器(数据结构之栈)
利用栈实现一个简易的计算器 实现了加减乘除运算(没有使用STL) 基本思想: 1.一个数据栈,一个符号栈 2.优先级判断 3.负号和减号的判别与处理 4.括号匹配 代码如下: #include<iostream> #include<string> #include<cstdlib> /*1、创建栈类,采用数组描述; 2、计算数学表达式的值。 输入数学表达式,输出表达式的计算结果。数学表达式由单个数字和 运算符“+”、“-”、“*”、“/”、“(”、“) ”构成,例如 2+3*(4+5)–6/4。 假定表达式
种花家的奋斗兔
2020/11/12
2.3K0
力扣227——227. 基本计算器 II
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。整数除法仅保留整数部分。
健程之道
2020/03/12
3410
相关推荐
用栈来实现简易版中缀表达式的计算器
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档