選擇棧作為資料結構,所以所有操作都要圍繞棧的特點來進行。因為先入棧而被壓在下面的意味著要後處理,
所以優先順序低的不能壓著優先順序高的而入棧。對於同級的操作符,因為要按照從左往右的運算規則,所以也不
能壓著同級的操作符而入棧。簡單來說,與棧頂的操作符比較,優先順序高的則入棧,否則操作符出棧作相應運
算。本演算法使用兩個棧,乙個用來存放操作符,乙個用來存放運算元和運算的結果。
因為比較優先順序是必須做的事,所以這是乙個核心問題,需要定乙個規則(這個規則在相應的函式中體現)。
本演算法對算術表示式的書寫是很嚴格的,本演算法不對表示式的合法性作檢查。
算術表示式格式例子如:#23+(5-2)*10/5-3#
我們所做的一切都是為了簡化問題的複雜度,特別是當你不知道怎麼編寫**或**寫的很亂的時候,你就應
該想方設法進行簡化,而編寫演算法是乙個有效的簡化方法(至少編寫演算法時會忽略不重要的細節)。
演算法思想:
1。初始化,運算元棧置空;操作符棧壓入'#'。
2。從左往右讀取算術表示式(從第二個字元開始),當讀到'#'且操作符棧棧頂也是'#'時則演算法結束。
3。如果讀到的是運算元則壓入運算元棧中,轉到步驟2。
4。如果讀到是操作符,則比較其與操作符棧棧頂操作符的優先順序。
5。如果棧頂操作符的優先順序高,則棧頂操作符出棧,並從運算元棧中彈出兩個運算元進行相應的運算,再把運
算結果壓入運算元棧中,轉至步驟4。
6。如果棧頂操作符的優先順序低,則把當前操作符壓入操作符棧,轉至步驟2。
7。如果棧頂操作符與當前操作符優先順序相同,則只可能是'('跟')',把操作符從棧中彈出即可,轉至步驟2。
演算法描述:
expression_compute( expresstion )
initstack( optrstack );
push( optrstack, '#' );
initstack( opndstack );
w = read( expresstion ); // 讀取乙個原子字元
while w != '#' or peek(optrstack) != '#'
[if isopnd( w ) // 如果是運算元
[push( opndstack, w );
w = read( expresstion ); // 讀取下乙個原子字元
]else
[b = precede( peek(optrstack), w );
if b == '<'
[push( optrstack, w );
w = read( expresstion );
]else if b == '='
[pop( optrstack ); // 只可能是'('
w = read( expresstion );
]else if b == '>'
[optr = pop( optrstack );
right = pop( opndstack );
left = pop( opndstack );
x = operate( left, optr, right );
push( opnd, x );] ]
]return peek(opndstack);
以下是實現**,棧("stack.h")的定義在文章<
using namespace std;
#include
#include
#include "stack.h"
using namespace _bs_stack;
/** #5+(7-8*12)/3+1#
*/typedef stack opndstack; // 運算元棧
typedef stack optrstack; // 操作符棧
void destroy( void * pdata )
opndstack opndstack( destroy );
optrstack optrstack( destroy );
// 讀取乙個原子字元
void read( char *& expression, char ret_buf )
ret_buf[ npos ] = '/0';
}else
}// 判斷是否是運算元
bool isopnd( char * expression )
// 優先順序比較,制定規則
char precede( char leftoptr, char rightoptr )
if ( leftoptr == '-' )
if ( leftoptr == '*' )
if ( leftoptr == '/' )
if ( leftoptr == '(' )
if ( leftoptr == ')' )
return '>';
if ( leftoptr == '#' )
return 'e';
}// 運算
int operate( int leftopnd, char optr, int rightopnd )
else return -999;
}// 主函式
int expression_compute( char * expression )
;read( expression, buf );
while ( strcmp( buf, "#" ) != 0 || *(char*)optrstack.peek() != '#' )
else
else if ( ret_char == '=' )
else if ( ret_char == '>' )}}
return *(int*)opndstack.peek( );
}// 測試函式
int main( )
;//strcpy( buf, "#1+20*2#" );
cout << "enter expression: ";
cin >> buf;
int ret = expression_compute( buf );
cout << buf << " == " << ret << endl;
return 1;
}
算術表示式求值 棧的應用
注 實驗用書為 資料結構 c語言版 第2版,人民郵電出版社出版。實驗題目 學生管理系統的設計與實現 實驗環境 visual c 6.0或其他c 環境 一 實驗目的 1 掌握棧的定義及實現 2 掌握利用棧求解算術表示式的方法。二 實驗內容 通過修改完善教材中的演算法3.4,利用棧來實現算術表示式求值的...
棧的應用 算術表示式求值
算術表示式中可以包含 這6個運算子,要計算的表示式以字串行的形式在程式執行時輸入。為了便於實現,規定 1 每個表示式均以字元 開始,以 號結束,例如,23 13 8 76 100 表示式中不能出現數字和運算子外的其它字元 空格也不行 2 表示式中的運算數只能是非負整數 3 輸入的表示式都是合法的。編...
棧的應用之算術表示式求值
1 2 3 4 此算術表示式由一些操作符和運算元組成。其中,操作符有 等,運算元有 1 2 3 等。對於操作符來說,其運算是有優先順序的。比如,上述表示式中,3 4應該先進行操作,將得到的結果再與2相乘。算符間的優先關係如下 運算子 根據算符間的優先關係表,使用兩個棧。乙個棧為optr,儲存運算子,...