本文实例讲述了PHP栈的定义、入栈出栈方法及基于堆栈实现的计算器。分享给大家供大家参考,具体如下:

栈是线性表的一种,他的特点是后入先出,可以这么理解,栈就像一个存东西的盒子,先放进去的在最底层,后放进去的在上层,因为上层的东西把底层的东西压住了,下层的想要出去就必须把上层的先拿开才行。

介绍代码:

data类:就是存放数据的类。()就是要放入栈的东西
stack类:是栈的类,整个对栈就在这个类中

主要方法:

入栈push_stack($data)检测栈是否已满,如果没满就让数据入栈。
出栈pop_stack($data)检测栈是否为空,如果不空可以出栈
读取栈顶元素top_stack()如果栈不空,返回当前栈顶部的数据。

下边是代码:

<?php
/**
* Author Been
**/
class data{
  //数据
  private $data;
  public function __construct($data){
    $this->data=$data;
    echo $data.":哥入栈了!<br>";
  }
  public function getData(){
    return $this->data;
  }
  public function __destruct(){
    echo $this->data.":哥走了!<br>";
  }
}
class stack{
  private $size;
  private $top;
  private $stack=array();
  public function __construct($size){
    $this->Init_Stack($size);
  }
  //初始化栈
  public function Init_Stack($size){
    $this->size=$size;
    $this->top=-1;
  }
  //判断栈是否为空
  public function Empty_Stack(){
    if($this->top==-1)return 1;
    else return 0;
  }
  //判断栈是否已满
  public function Full_Stack(){
    if($this->top<$this->size-1)return 0;
    else return 1;
  }
  //入栈
  public function Push_Stack($data){
    if($this->Full_Stack())echo "栈满了<br />";
    else $this->stack[  $this->top]=new data($data);
  }
  //出栈
  public function Pop_Stack(){
    if($this->Empty_Stack())echo "栈空着呢<br />";
    else unset($this->stack[$this->top--]);
  }
  //读取栈顶元素
  public function Top_Stack(){
    return $this->Empty_Stack()?"栈空无数据!":$this->stack[$this->top]->getData();
  }
}
$stack=new stack(4);
$stack->Pop_Stack();
$stack->Push_Stack("aa");
$stack->Push_Stack("aa1");
$stack->Pop_Stack("aa1");
$stack->Push_Stack("aa2");
$stack->Push_Stack("aa3");
$stack->Push_Stack("aa4");
echo $stack->Top_Stack(),'<br />';
$stack->Push_Stack("aa5");
$stack->Push_Stack("aa6");
$stack->Pop_Stack();
$stack->Pop_Stack();
$stack->Pop_Stack();
$stack->Pop_Stack();
$stack->Pop_Stack();
$stack->Pop_Stack();

运行结果:

栈空着呢
aa:哥入栈了!
aa1:哥入栈了!
aa1:哥走了!
aa2:哥入栈了!
aa3:哥入栈了!
aa4:哥入栈了!
aa4
栈满了
栈满了
aa4:哥走了!
aa3:哥走了!
aa2:哥走了!
aa:哥走了!
栈空着呢
栈空着呢

案例:基于堆栈的高级计算器

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

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

思路是这样的:(我们利用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();
?>

运行结果:

12 5*2 3-5*2=15

PS:这里再为大家推荐几款计算工具供大家进一步参考借鉴:

在线一元函数(方程)求解计算工具:
http://tools.jb51.net/jisuanqi/equ_jisuanqi

科学计算器在线使用_高级计算器在线计算:
http://tools.jb51.net/jisuanqi/jsqkexue

在线计算器_标准计算器:
http://tools.jb51.net/jisuanqi/jsq

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP数学运算技巧总结》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《PHP数组(Array)操作技巧大全》、《PHP数据结构与算法教程》、《php程序设计算法总结》及《php正则表达式用法总结》

希望本文所述对大家PHP程序设计有所帮助。

PHP栈的定义、入栈出栈方法及基于堆栈实现的计算器完整实例的更多相关文章

  1. 从iOS应用程序发送帖子到PHP脚本不工作…简单的解决方案就像

    我之前已经做了好几次了但是由于某些原因我无法通过这个帖子…我尝试了设置为_POST且没有的变量的PHP脚本……当它们未设置为发布时它工作精细.这是我的iOS代码:这里是PHP的一大块,POST变量不在正确的位置?我想这对于更有经验的开发人员来说是一个相当简单的答案,感谢您的帮助!解决方法$_POST是一个数组,而不是一个函数.您需要使用方括号来访问数组索引:

  2. swift学习2 元组 tuples

    swift中出现了一种新的数据结构,非常牛掰的元组tuples如果懂PHP的猿,会发现这个元组和PHP的数组非常类似,同样是可以默认不指定key,也可以指定key目前的学习疑问是,如何进行元组的遍历?

  3. 尝试使用swift mailer,gmail smtp,php发送邮件

    这里是我的代码:在运行时出现此错误…

  4. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  5. jQuery的Cookie封装,与PHP交互的简单实现

    下面小编就为大家带来一篇jQuery的Cookie封装,与PHP交互的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  7. 如何在PHP环境中使用ProtoBuf数据格式

    这篇文章主要介绍了如何在PHP环境中使用ProtoBuf数据格式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  8. PHP rsa加密解密算法原理解析

    这篇文章主要介绍了PHP rsa加密解密算法原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  9. 基于JavaScript实现网页计算器

    这篇文章主要为大家详细介绍了基于JavaScript实现网页计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. PHP cookie与session会话基本用法实例分析

    这篇文章主要介绍了PHP cookie与session会话基本用法,结合实例形式分析了PHP cookie与session会话基本存储、设置、删除等相关使用方式,需要的朋友可以参考下

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部