用鏈棧實現簡易四則運算計算器(php版)

棧是一種限定僅在表尾進行插入和刪除操做的線性表。棧的應用有不少,好比常見的遞歸,計算機表達式求值等。下面咱們用棧來實現簡易的四則運算計算器。

列一下本文的思路:node

  1. 實現鏈棧的數據結構及其操做
  2. 中綴表達式轉後綴表達式
  3. 後綴表達式求值
一、首先, 先實現一個鏈棧。
//定義棧的數據結構
class Node
{
    public $symbol;
    public $next;

    public function __construct( $symbol, $next )
    {
        $this->symbol = $symbol;
        $this->next   = $next;
    }
}

//初始化棧,生成頭結點
function initStack( &$node )
{
    $node = new Node( '', null );
}

//入棧
function push( Node &$node, $symbol )
{
    $p          = new Node( $symbol, null );
    $p->next    = $node->next;
    $node->next = $p;
}

//出棧
function pop( Node &$node, &$symbol )
{
    if ( null == $node->next ) {
        echo "棧空\n";

        return;
    }

    $q          = $node->next;
    $symbol     = $q->symbol;
    $node->next = $node->next->next;
    unset( $q );
}
二、其次, 利用第一步實現的鏈棧,將中綴表達式轉爲後綴表達式。
//獲取運算符的優先級
function get_priority( $symbol )
{
    switch ( $symbol ) {
        case '(':
            $priority = 3;
            break;
        case '*':
        case '/':
            $priority = 2;
            break;
        case '+':
        case '-':
            $priority = 1;
            break;
        case ')':
            $priority = 0;
            break;
        default:
            $priority = 0;
            break;
    }

    return $priority;
}

//棧頂依次出棧,若是遇到'('則中止
function clear_stack( &$list )
{
    $res = '';
    while ( null != $list->next ) {
        if ( '(' != $list->next->symbol ) {
            pop( $list, $item );
            $res .= $item;

        } else {
            pop( $list, $item );

            return $res;
        }
    }

    return $res;
}

//中綴表達式轉後綴表達式
function middle_to_back( $middle_expression )
{
    initStack( $list );
    $back_expression = '';
    $length          = strlen( $middle_expression );
    for ( $i = 0; $i < $length; $i ++ ) {
        $symbol = $middle_expression[ $i ];
        if ( ' ' != $symbol ) {
            if ( is_numeric( $symbol ) ) { //數字直接輸出
                $back_expression .= $symbol;
            } else {//非數字則比較優先級
                $stack_top_priority      = get_priority( null == $list->next ? '' : $list->next->symbol );
                $current_symbol_priority = get_priority( $symbol );
                if ( $current_symbol_priority > $stack_top_priority ) {//優先級比棧頂高則進棧
                    push( $list, $symbol );
                } else {
                    $output          = clear_stack( $list );
                    $back_expression .= $output;
                    if ( ')' != $symbol ) {
                        push( $list, $symbol );
                    }
                }
            }
        }
    }

    while ( null != $list->next ) {//將棧清空
        pop( $list, $item );
        $back_expression .= $item;
    }

    return $back_expression;
}
三、接下來, 咱們利用第一步實現的鏈棧,和第二步獲得的後綴表達式,計算最後的值。
//是不是四則運算符號
function is_arithmetic_symbol( $symbol )
{
    $arithmetic_symbols = array( '+', '-', '*', '/' );
    if ( in_array( $symbol, $arithmetic_symbols ) ) {
        return true;
    } else {
        return false;
    }
}

//計算後綴表達式的值
function calculate( $expression )
{
    $stack  = new Node( '', null );
    $length = strlen( $expression );
    for ( $i = 0; $i < $length; $i ++ ) {
        if ( ' ' != $expression[ $i ] ) {//爲空則跳過
            if ( is_numeric( $expression[ $i ] ) ) {
                push( $stack, $expression[ $i ] );
            } else if ( is_arithmetic_symbol( $expression[ $i ] ) ) {
                pop( $stack, $n1 );
                pop( $stack, $n2 );
                $res = get_result( $n2, $n1, $expression[ $i ] );
                push( $stack, $res );
            } else {
                echo "wrong symbol, exit";
                exit();
            }
        }
    }

    $value = $stack->next->symbol;

    return $value;
}
最後,咱們測試一下所實現的計算器。
function main()
{
    $back_expression = middle_to_back( '((1+2)*3-4) * 5' );
    $result          = calculate( $back_expression );
    echo "後綴表達式的值爲: " . $back_expression, PHP_EOL;
    echo "result : " . $result, PHP_EOL;
}

main();

獲得的結果以下: express

clipboard.png

簡易的計算器就實現啦!~~~
(代碼中有一些細節未作判斷,但願讀者理解。歡迎你們提出批評修改意見,感謝~)數據結構

相關文章
相關標籤/搜索