**:
1 本文目標
分析用堆疊解析算術表示式的基本方法。給出的示例**能解析任何包括+,-,*,/,()和0到9數字組成的算術表示式。
2 中綴表示式和字尾表示式
中綴表示式就是通常所說的算術表示式,比如(1+2)*3-4。
字尾表示式是指通過解析後,運算子在運算數之後的表示式,比如上式解析成字尾表示式就是12+3*4-。這種表示式可以直接利用棧來求解。
3 運算子的優先順序
優先順序運算子
1括號()
2負號-
3乘方**
4乘*,除/,求餘%
5加+,減-
6小於<,小於等於<=,大於》,大於等於》=
7等於==,不等於!=
8邏輯與&&
9邏輯或||
大致的規律是,一元運算子 > 二元運算子 > 多元運算子。
4 利用堆疊解析算術表示式的過程
中綴表示式翻譯成字尾表示式的方法如下:
(1)從右向左依次取得資料ch。
(2)如果ch是運算元,直接輸出。
(3)如果ch是運算子(含左右括號),則:
a:如果ch = '(',放入堆疊。
b:如果ch = ')',依次輸出堆疊中的運算子,直到遇到'('為止。
c:如果ch不是')'或者'(',那麼就和堆疊頂點位置的運算子top做優先順序比較。
1:如果ch優先順序比top高,那麼將ch放入堆疊。
2:如果ch優先順序低於或者等於top,那麼輸出top,然後將ch放入堆疊。
(4)如果表示式已經讀取完成,而堆疊中還有運算子時,依次由頂端輸出。
如果我們有表示式(a-b)*c+d-e/f,要翻譯成字尾表示式,並且把字尾表示式儲存在乙個名叫output的字串中,可以用下面的步驟。
(1)讀取'(',壓入堆疊,output為空
(2)讀取a,是運算數,直接輸出到output字串,output = a
(3)讀取'-',此時棧裡面只有乙個'(',因此將'-'壓入棧,output = a
(4)讀取b,是運算數,直接輸出到output字串,output = ab
(5)讀取')',這時候依次輸出棧裡面的運算子'-',然後就是'(',直接彈出,output = ab-
(6)讀取'*',是運算子,由於此時棧為空,因此直接壓入棧,output = ab-
(7)讀取c,是運算數,直接輸出到output字串,output = ab-c
(8)讀取'+',是運算子,它的優先順序比'*'低,那麼彈出'*',壓入'+",output = ab-c*
(9)讀取d,是運算數,直接輸出到output字串,output = ab-c*d
(10)讀取'-',是運算子,和'+'的優先順序一樣,因此彈出'+',然後壓入'-',output = ab-c*d+
(11)讀取e,是運算數,直接輸出到output字串,output = ab-c*d+e
(12)讀取'/',是運算子,比'-'的優先順序高,因此壓入棧,output = ab-c*d+e
(13)讀取f,是運算數,直接輸出到output字串,output = ab-c*d+ef
(14)原始字串已經讀取完畢,將棧裡面剩餘的運算子依次彈出,output = ab-c*d+ef/-
5 計算算術表示式
當有了字尾表示式以後,運算表示式的值就非常容易了。可以按照下面的流程來計算。
(1)從左向右掃瞄表示式,乙個取出乙個資料data
(2)如果data是運算元,就壓入堆疊
(3)如果data是操作符,就從堆疊中彈出此操作符需要用到的資料的個數,進行運算,然後把結果壓入堆疊
(4)如果資料處理完畢,堆疊中最後剩餘的資料就是最終結果。
比如我們要處理乙個字尾表示式1234+*+65/-,那麼具體的步驟如下。
(1)首先1,2,3,4都是運算元,將它們都壓入堆疊
(2)取得'+',為運算子,彈出資料3,4,得到結果7,然後將7壓入堆疊
(3)取得'*',為運算子,彈出資料7,2,得到資料14,然後將14壓入堆疊
(4)取得'+',為運算子,彈出資料14,1,得到結果15,然後將15壓入堆疊
(5)6,5都是資料,都壓入堆疊
(6)取得'/',為運算子,彈出資料6,5,得到結果1.2,然後將1.2壓入堆疊
(7)取得'-',為運算子,彈出資料15,1.2,得到資料13.8,這就是最後的運算結果
6 示例**
//////
將中綴表示式翻譯成字尾表示式
///輸入中綴表示式: a+b*(c+d)-e/f
///翻譯成字尾表示式:abcd+*+ef/-
///中綴表示式翻譯成字尾表示式的方法如下:
///(1)從左向右依次取得資料ch
///(2)如果ch是運算元,直接輸出
///(3)如果ch是運算子(含左右括號),則:
///a:如果ch = '(',放入堆疊
///b:如果ch = ')',依次輸出堆疊中的運算子,直到遇到'('為止
///c:如果ch不是')'或者'(',那麼就和堆疊頂點位置的運算子top做優先順序比較
///1:如果ch優先順序比top高,那麼將ch放入堆疊
///2:如果ch優先順序低於或者等於top,那麼輸出top,然後將ch放入堆疊
///(4)如果表示式已經讀取完成,而堆疊中還有運算子時,依次由頂端輸出
/*pseudocode()
", expression);
console.writeline(
"the posfix expression is:
", parse());
console.writeline(
"the result is
", calculate());
console.read();}//
將中綴表示式解析成字尾表示式
public
static
string
parse()
else
}else
//既不是'(',也不是')',是其它操作符,比如+, -, *, /之類的
else
//如果棧頂元素的優先順序比較高或者兩者相等時}}
while( !
isempty(mystack));
}else
//如果堆疊為空,就把操作符放入堆疊中}}
}while( !
isempty(mystack ) )
b[j++] =
(char
)mystack.pop();
//將堆疊中剩下的操作符輸出到b中
for(i=0
; i<
b.length; i++)
if( b[i] !='
\0') //
去除多餘的空字元
return
posfixexpression.tostring();}//
計算字尾表示式的值
public
static
double
calculate()
else
//如果是操作符,就彈出兩個數字來進行運算
}return
(double
)mystack.pop();
//彈出最後的運算結果}//
對兩個值利用運算子計算結果
private
static
double
getvalue(
char
op,
double
ch1,
double
ch2)}//
判斷堆疊是否為空
private
static
bool
isempty(stack st)
//判斷是否是運算元
private
static
bool
isoperand(
char
ch )
;for
(inti=
0; i
<
operators.length; i++)
if( ch
==operators[i] )
return
false
;return
true;}
//返回運算子的優先順序
private
static
intpriority(
char
ch )
return
priority;}}
利用棧解析算術表示式
在沒有接觸到棧這種資料結構時,一直覺得用程式計算四則表示式是件相當繁瑣的事。但利用棧,問題就立刻變得容易許多。解析任何包括 和0到9數字組成的算術表示式,並計算其結果。中綴表示式就是通常所說的算術表示式,比如 1 2 3 4。字尾表示式是指通過解析後,運算子在運算數之後的表示式,比如上式解析成字尾表...
解析算術表示式
現有字串形式的算術表示式,求計算其值。string str1 2000 600 3 300 2 string str2 2000 600.389895334 2 300 2 6 100 求解方法如下 讀取公式,返回結果。param express 算術公式 return 結果字串 保留兩位小數 pu...
利用堆疊進行表示式求值
基本策略 將中綴表示式轉換為字尾表示式,然後求值 中綴表示式轉換為字尾表示式的流程 從頭到尾讀取中綴表示式的每個物件,對不同的物件按不同的情況處理 1 運算數 直接輸出 2 左括號 壓入堆疊,入棧前左括號的優先順序最高,入棧之後其優先順序降到最低 3 右括號 將棧頂的運算子彈出並輸出,直到遇到左括號...