基本策略:將中綴表示式轉換為字尾表示式,然後求值
中綴表示式轉換為字尾表示式的流程:
從頭到尾讀取中綴表示式的每個物件,對不同的物件按不同的情況處理
(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.將當前符號與棧頂符號比較優先順序...