PHP基於堆棧實現的進階計算機

來源:互聯網
上載者:User
這篇文章主要介紹了PHP基於堆棧實現的進階計算機功能,涉及php堆棧的定義及使用堆棧進行數值運算的相關操作技巧,需要的朋友可以參考下

本文執行個體講述了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=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();?>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.