고급 계산기를 구현한 PHP 함수 예제(스택 기반)

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

이 글은 주로 스택을 기반으로 PHP가 구현하는 고급 계산기 기능을 소개하며, PHP 스택의 정의와 스택을 사용하여 수치 연산을 수행하는 관련 운영 기술을 소개합니다.

이 문서의 예는 다음과 같습니다. 이 기사에서는 스택 고급 계산기 기능을 기반으로 하는 PHP 구현을 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 세부 사항은 다음과 같습니다.

문자열 연산 표현식을 얻을 때 연산 결과는 어떻게 얻나요?

이제 우리는 스택 알고리즘을 사용하여 이 문제를 매우 영리하게 해결할 수 있습니다.

아이디어는 다음과 같습니다. (우리는 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();
?>
로그인 후 복사

위 내용은 고급 계산기를 구현한 PHP 함수 예제(스택 기반)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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