> 백엔드 개발 > PHP 튜토리얼 > PHP 스택의 정의, 푸시 및 풀 메소드, 계산기의 전체 구현 예

PHP 스택의 정의, 푸시 및 풀 메소드, 계산기의 전체 구현 예

黄舟
풀어 주다: 2023-03-16 21:30:02
원래의
1755명이 탐색했습니다.

스택은 선형 테이블의 일종으로 나중에 들어온 것이 먼저 나가는 것입니다. 스택은 물건을 먼저 넣는 상자와 같고, 물건을 넣는 곳과 같다고 이해할 수 있습니다. 마지막으로 상위 레이어에 있는 것들이 하위 레이어에 있는 것들을 억압하고 있기 때문에, 하위 레이어에 있는 것들이 밖으로 나가려면 먼저 상위 레이어에 있는 것들을 제거해야 합니다.

소개 코드:

데이터 클래스: 데이터를 저장하는 클래스입니다. ()는 스택에 넣을 내용입니다
스택 클래스: 스택의 클래스입니다. 전체 스택이 이 클래스에 있습니다

메인 메소드:

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(),&#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이라고 가정합니다. 더 큰 숫자가 더 높은 우선순위를 갖는다고 가정합니다. 이런 식으로 우리는 연산자를 얻을 수 있습니다. 우선순위) 삽입할 기호가 스택 상단에 있는 연산자의 우선순위보다 작거나 같을 경우 숫자 스택에서 두 개의 값을 팝업하고 다음에서 연산자를 팝업합니다. 심볼 스택을 연산]

다음은 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿