ホームページ  >  記事  >  バックエンド開発  >  PHPスタックの定義、プッシュメソッドとポップメソッド、および計算機の完全な実装例

PHPスタックの定義、プッシュメソッドとポップメソッド、および計算機の完全な実装例

黄舟
黄舟オリジナル
2017-11-02 09:10:241751ブラウズ

スタックはリニアテーブルの一種で、後入れ先出しで、最初に入れるものは一番下の層にある、ということが分かります。最後に入れるのは上の層にあるため、下の層にあるものは下の層にあるものを抑制しているため、最下層にあるものを外に出したい場合は、最初に上の層にあるものを取り除かなければなりません。 。

紹介コード:

dataクラス: データを格納するクラスです。 () はスタックに入れるものです
スタッククラス: スタッククラスであり、スタック全体がこのクラス内にあります

メインメソッド:

Push Push_stack ($data) はスタックがいっぱいかどうかを検出します満たされていない場合は、データをスタックにプッシュします。
スタックが空かどうかを確認するには、pop_stack($data)を実行します。
スタックが空でない場合は、スタックの先頭要素を読み込みます。現在のスタックの先頭にあるデータ。

以下はコードです:

<?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(),&#39;<br />&#39;;
$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 であると仮定します。数値が大きいほど優先順位が高いと仮定するので、演算子の優先順位を取得できます)挿入されるシンボルの優先度がスタックの先頭の演算子の優先度以下の場合、数値スタックから 2 つの値がポップアップし、シンボル スタックから演算子がポップアップします。それらを操作してください]以下は PHP の例です [ハン シュンピン先生の PHP アルゴリズム チュートリアルを参照してください]

<html>
<head>
<meta http-equiv=&#39;content-type&#39; content=&#39;text/html;charset=utf-8&#39;/>
</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 &#39;<br/>栈满,不能添加&#39;;
          return;
        }
        $this->top++;
        $this->stack[$this->top]=$val;
      }
      //出栈的操作,就是把栈顶的值取出
      public function pop()
      {
        //判断是否栈空
        if($this->top==-1){
          echo &#39;<br/>栈空1&#39;;
          return;
        }
        //把栈顶的值,取出
        $topVal=$this->stack[$this->top];
        $this->top--;
        return $topVal;
      }
      //显示栈的所有数据的方法.
      public function showStack()
      {
        if($this->top==-1){
          echo &#39;<br/>栈空2&#39;;
          return;
        }
        echo &#39;<br/>当前栈的情况是....&#39;;
        for($i=$this->top;$i>-1;$i--){
          echo &#39;<br/> stack[&#39;.$i.&#39;]=&#39;.$this->stack[$i];
        }
      }
      //判断是否是一个运算符
      public function isOper($val)
      {
        if ($val==&#39;+&#39;||$val==&#39;-&#39;||$val==&#39;*&#39;||$val==&#39;/&#39;)
        {
          return true;
        }
      }
      //判断栈是否为空
      public function isEmpty()
      {
        if ($this->top==-1) return true;
      }
      /**
       * 比较运算符的优先级
       * 我把 * 和/运算符的优先级看作1
       * +和- 看作0
       * 通过它们之间的比较就能得出它们的优先级谁更高
       */
      public function PRI($oper)
      {
        if ($oper==&#39;*&#39;||$oper==&#39;/&#39;)
        {
          return 1;
        } else if ($oper==&#39;+&#39;||$oper==&#39;-&#39;) {
          return 0;
        }
      }
      //返回栈顶端的值
      public function getTop()
      {
        return $this->stack[$this->top];
      }
      //计算
      public function getResult($num1,$num2,$oper)
      {
        switch ($oper)
        {
          case &#39;+&#39;:
            $res = $num2+$num1;
          break;
          case &#39;-&#39;:
            $res = $num2-$num1;
          break;
          case &#39;*&#39;:
            $res = $num2*$num1;
          break;
          case &#39;/&#39;:
            $res = $num2/$num1;
          break;
        }
        return $res;
      }
}
//需要进行运算的表达式
$str = &#39;12+5*2+3-5*2&#39;;
//字符串的指针
$index = 0;
//声明一个用于组合联系数字的变量
$keepNum = &#39;&#39;;
//定义一个数栈和一个符号栈
$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=&#39;&#39;;
      }
    }
  }
  $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.&#39;=&#39;.$numsStack->getTop();
?>

実行結果:

12+5*2+3-5*2=15

以上がPHPスタックの定義、プッシュメソッドとポップメソッド、および計算機の完全な実装例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。