利用堆疊進行表示式求值

2021-10-19 15:08:13 字數 3387 閱讀 4080

基本策略:將中綴表示式轉換為字尾表示式,然後求值

中綴表示式轉換為字尾表示式的流程:

從頭到尾讀取中綴表示式的每個物件,對不同的物件按不同的情況處理

(1) 運算數:直接輸出

(2) 左括號:壓入堆疊,入棧前左括號的優先順序最高, 入棧之後其優先順序降到最低

(3) 右括號:將棧頂的運算子彈出並輸出,直到遇到左括號(出棧,不輸出)

(4) 運算子:

[1] 若優先順序大於棧頂運算子時,則把它壓棧

[2] 若優先順序小於棧頂運算子時,將棧頂運算子彈出並輸出;再比較新的棧頂運算子,直到該運算子大於棧頂運算子為止,然後將該運算子壓棧;

(4) 若各物件處理完畢,則把堆疊中存留的運算子一併輸出

#pragma once

#include /*

表示式運算, 實現基本的表示式求值, 支援運算子: +, -, *, /, (, )

*/class cexpressoperation

; // 定義堆疊

struct snode

};// 將字元中綴表示式轉換為鏈**式

bool infixtolink(char* infix, snode& link);

// 中綴表示式轉換為字尾表示式

bool infixtosuffix(snode& lkinfix, snode& lksuffix);

// 字尾表示式求值

bool calsuffix(snode& lksuffix, double& result);

// 刪除堆疊

void delstack(snode& stack);

// 入棧

void stackpush(snode& stack, snode* pnode);

// 出棧

bool stackpop(snode& stack, snode& node);

// 棧是否為空

bool isstackempty(snode& stack);

// 在鍊錶末端插入

void linkaddtail(snode& link, snode* pnode);

// 順序列印

void linkprint(snode& link);

};

#include "expressoperation.h"

#include #include #include #define opr_add 2

#define opr_sub 2

#define opr_mul 3

#define opr_div 3

#define opr_left 4 // 左括號

#define opr_right 4 // 右括號

#define opr_sleft 1 // 左括號入棧後優先順序降為最低

cexpressoperation::cexpressoperation()

cexpressoperation::~cexpressoperation()

// 輸入乙個中綴表示式,求出結果

bool cexpressoperation::calculatevalue(char* infix, double& result)

if (!infixtosuffix(lkinfix, lksuffix))

bool bret = calsuffix(lksuffix, result);

delstack(lkinfix);

delstack(lksuffix);

return bret;

}// 將字元中綴表示式轉換為鏈**式

bool cexpressoperation::infixtolink(char* infix, snode& link)

if (infix[ie] == ' ' || infix[ie] == '\t')

switch (infix[ie])

if (ib > 0)

pnode = new snode();

pnode->type = 1;

pnode->sopr = sopr;

linkaddtail(link, pnode);

ie++;

break;

} if (ib > 0)

}return true;

}// 中綴表示式轉換為字尾表示式

bool cexpressoperation::infixtosuffix(snode& lkinfix, snode& lksuffix)

else

else if (pinf->sopr.type == ')')}}

else

else

}if (!bpush)

}} pinf = pinf->pnext;

} // 處理結束後, 還需要檢查堆疊的元素, 不為空則全部彈出

while (!isstackempty(skopr)) }

delstack(skopr);

return true;

}// 字尾表示式求值

bool cexpressoperation::calsuffix(snode& lksuffix, double& result)

else

stackpush(skval, psk);

} psuf = psuf->pnext;

} if (!stackpop(skval, top1))

result = top1.val;

delstack(skval);

return true;

}// 刪除堆疊

void cexpressoperation::delstack(snode& stack)

}// 入棧

void cexpressoperation::stackpush(snode& stack, snode* pnode)

// 出棧

bool cexpressoperation::stackpop(snode& stack, snode& node)

// 棧是否為空

bool cexpressoperation::isstackempty(snode& stack)

// 在鍊錶末端插入

void cexpressoperation::linkaddtail(snode& link, snode* pnode)

ptail->pnext = pnode;

pnode->pnext = null;

}// 順序列印

void cexpressoperation::linkprint(snode& link)

pnode = pnode->pnext;

} printf("\n");

}

利用棧和佇列進行表示式求值

深入了解棧和佇列的特性,學會在實際問題下靈活運用它們。表示式求值運算是實現程式語言的基本問題之一,也是棧應用的乙個典型例子。設計並演示用算符優先順序對算術表示式的求解過程。1 演算法優先級別如下 2 以字串行的形式從終端輸入語法正確 不含變數的算術表示式,利用給出的算符優先順序關係,實現對算術四則混...

堆疊經典應用 表示式求值 字尾表示式

引言 表示式求值的思路可以是直接處理中綴表示式,也可以採用字尾表示式進行轉換求值,這篇文章將按照以下思路 優先順序的概念 什麼是中綴字尾表示式 字尾表示式的優點 中綴表示式如何轉換為字尾表示式 字尾表示式的運算 具體 實現 優先順序 表示式求值是乙個資料結構中的經典問題,要求對表示式中的運算優先順序...

堆疊的應用 中綴表示式求值

分析 應先將中綴表示式轉換為字尾表示式 中綴轉字尾的步驟 1.首先依次按順序考慮字尾表示式中的各個運算數和運算符號,所有未處理的符號稱為等待中的符號 2.碰到運算數時直接輸出 3.碰到運算符號時,現將運算符號入棧,比較當前棧頂的符號和等待中的下乙個符號的優先順序 4.將當前符號與棧頂符號比較優先順序...