国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

php簡(jiǎn)單實(shí)現(xiàn)算術(shù)表達(dá)式轉(zhuǎn)換成逆波蘭式并求解

2020-03-22 17:50:37
字體:
供稿:網(wǎng)友
  • 最近一直在學(xué)習(xí)C/C++,可學(xué)的都是原理語法之類的,沒有實(shí)戰(zhàn)成績(jī)甚是令人不爽。想用C/C++寫個(gè)計(jì)算器一直是我的夙愿,剛敲鍵盤,就不知可否了,想來想去還是對(duì)計(jì)算器的算法不是很清楚。由于本人是學(xué)php出身,所以先使用php將計(jì)算器算法給實(shí)現(xiàn)了一下,以便更好的學(xué)習(xí)C/C++。這個(gè)簡(jiǎn)單的計(jì)算器采用的是逆波蘭式來做的,僅支持加減乘除四種運(yùn)算,純粹個(gè)人練習(xí)記錄一下,還望多多支持。

    將算術(shù)表達(dá)式轉(zhuǎn)換成逆波蘭式
      建立運(yùn)算符棧stackOperator用于運(yùn)算符的存儲(chǔ),壓入'@';建立逆波蘭式存儲(chǔ)棧stackOut,并置空。預(yù)處理表達(dá)式,正、負(fù)號(hào)前加0(如果一個(gè)加號(hào)(減號(hào))出現(xiàn)在最前面或左括號(hào)后面,則該加號(hào)(減號(hào))為正負(fù)號(hào)) 。順序掃描表達(dá)式,如果當(dāng)前字符是數(shù)字(優(yōu)先級(jí)為0的符號(hào)),則直接入棧stackOut;如果當(dāng)前字符為運(yùn)算符或括號(hào)(優(yōu)先級(jí)不為0的符號(hào)),則判斷第4點(diǎn) 。若當(dāng)前運(yùn)算符為'(',直接入棧stackOperator;
      若為')',出棧(stackOperator)并順序輸出運(yùn)算符直到遇到第一個(gè)'(',遇到的第一個(gè)'(' 出棧(stackOperator)但不輸出;
      若為四則運(yùn)算符,比較棧頂元素與當(dāng)前元素的優(yōu)先級(jí):
      如果棧頂元素運(yùn)算符優(yōu)先級(jí) >= 當(dāng)前元素的優(yōu)先級(jí), 出棧并順序輸出運(yùn)算符直到棧頂元素優(yōu)先級(jí)<當(dāng)前元素優(yōu)先級(jí),然后將當(dāng)前元素入棧(stackOperator);
      如果棧頂元素的優(yōu)先級(jí)>當(dāng)前元素的優(yōu)先級(jí),直接入棧(stackOperator)。重復(fù)第3點(diǎn)直到表達(dá)式掃描完畢。順序出棧(stackOperator)并將輸出的元素壓入棧stackOut,直到棧頂元素為'@'。
    計(jì)算逆波蘭式
      準(zhǔn)備一個(gè)棧stack,并置空。順序讀取(從棧底到棧頂)棧stackOut,碰到操作數(shù),入棧stack。 www.it165.net碰到操作符,stack彈出兩個(gè)元素,運(yùn)算并將運(yùn)算結(jié)果入棧stack。重復(fù)執(zhí)行2~3步驟,棧stack即是表達(dá)式結(jié)果。
    實(shí)現(xiàn)代碼
    /** * php簡(jiǎn)單實(shí)現(xiàn)算術(shù)表達(dá)式轉(zhuǎn)換成逆波蘭式,并求解。 * 僅支持加減乘除四種運(yùn)算 * @author joe, joenali@163.com * @date 2013-01-17 * <pre> *  require 'Calc.php'; *  $calc = new Calc('(1+9)/2'); *  echo $calc->getExpression(); *  echo $calc->calculate(); * </pre> */html' target='_blank'>class Calc {    protected $_stackOperator = array('@');    protected $_stackOut = array();    protected $_operator = array('@', '(', ')', '+', '-', '*', '/');    protected $_priority = array('@' => 0, '(' => 10, ')' => 10, '+' => 20, '-' => 20, '*' => 30, '/' => 30);    public function __construct($expression) {        $this->convert($expression);    }    /**     * 解析字符串表達(dá)式     * 解析字符串表達(dá)式,將數(shù)字和運(yùn)算符分離,用數(shù)組存儲(chǔ)     * @param string $expression     * @return array     */    protected function expressionParase($expression) {        $arr = str_split($expression);        $data = $tmp = array();        do {            $item = array_shift($arr);            if (in_array($item, $this->_operator)) {                if ($tmp) {                    array_push($data, implode('', $tmp));                    $tmp = array();                }                array_push($data, $item);            } else {                array_push($tmp, $item);            }        } while(count($arr));        array_push($data, implode('', $tmp));        return $data;    }    /**     * 生成逆波蘭式     * @param string $expression     */    protected function convert($expression) {        foreach ($this->expressionParase($expression) as $char) {            if (preg_match("/^[0-9]+$/", $char)) {                array_push($this->_stackOut, $char);            } else if (in_array($char, $this->_operator)) {                if ('(' == $char) {                    array_push($this->_stackOperator, $char);                } else if (')' == $char) {                    while (count($this->_stackOperator) > 1) {                        $drop = array_pop($this->_stackOperator);                        if ('(' == $drop) {                            break;                        } else {                            array_push($this->_stackOut, $drop);                        }                    }                } else {                    while (count($this->_stackOperator)) {                        $oTop = end($this->_stackOperator);                        if ($this->_priority[$char] > $this->_priority[$oTop]) {                            array_push($this->_stackOperator, $char);                            break;                        } else {                           $drop = array_pop($this->_stackOperator);                            array_push($this->_stackOut, $drop);                        }                    }                }            }        }        while (count($this->_stackOperator)) {            $drop = array_pop($this->_stackOperator);            if ('@' == $drop) {                break;            } else {                array_push($this->_stackOut, $drop);            }        }    }    /**     * 獲取逆波蘭式     * @return string     */    public function getExpression() {        return implode('', $this->_stackOut);    }    /**     * 計(jì)算逆波蘭式     * @return int     */    public function calculate() {        $stack = array();        foreach ($this->_stackOut as $char) {            if (preg_match("/^[0-9]+$/", $char)) {                array_push($stack, $char);            } else if (in_array($char, $this->_operator)) {                $b = array_pop($stack);                $a = array_pop($stack);                array_push($stack, $this->operator($a, $b, $char));            }        }        return end($stack);    }    protected function operator($a, $b, $o) {        switch ($o) {            case '+':                return intval($a) + intval($b);                break;            case '+':                return intval($a) + intval($b);                break;            case '-':                return intval($a) - intval($b);                break;            case '*':                return intval($a) * intval($b);                break;            case '/':                return intval($a) / intval($b);                break;        }    }}

    PHP編程

    鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

  • 發(fā)表評(píng)論 共有條評(píng)論
    用戶名: 密碼:
    驗(yàn)證碼: 匿名發(fā)表
    主站蜘蛛池模板: 张家界市| 曲周县| 习水县| 江达县| 乃东县| 伊川县| 南部县| 孝昌县| 体育| 金华市| 沂南县| 沧源| 肇庆市| 昌黎县| 滨州市| 和顺县| 东阳市| 信宜市| 延长县| 靖安县| 大名县| 浪卡子县| 屏南县| 龙口市| 青海省| 普格县| 蚌埠市| 武穴市| 广水市| 黑山县| 大厂| 喀喇| 龙门县| 崇礼县| 洛浦县| 安阳县| 乐昌市| 许昌市| 仙居县| 烟台市| 江山市|