表示式(四則運算)計算的演算法
通常我們所看到的算術表示式,運算子總是在兩個運算元中間
(除),如
(a+b)*c,
這樣的表示式叫做
中綴表示式。這種表示式不同的運算子優先順序不同,而且通常含有括號,計算機很難理解這種表示式。在編譯系統中,要把人易於理解的表示式翻譯成能正確求值的機器指令。編譯系統中對中綴形式的算術表示式的處理方式是: 先把中綴表示式轉換成字尾表示式,再進行計算。
字尾表示式就
是表示式中的運算子出現在運算元的後面,並且不含括號,如ab+c*。字尾表示式的特點:
(1).字尾表示式讓運算元和中綴表示式的運算元先後次序相同,只是運算子的先後次序改變;
(2).字尾表示式沒有括號,運算次序就是其執行次序。
在計算機內部,任何乙個表示式都是由運算元、運算子和分界符組成。運算元和運算子是表示式的主要部分,分界符
(如用#表示)
標誌了乙個表示式的結束。我們把運算元、運算子和分界符稱為表示式的
單詞。
乙個中綴表示式的四則運算規則: 1.
先乘除後加減 2.
先括號內後括號外 3.
同級別時先左後右
下面以a+(b-c/d)*e為例對過程進行講解。a+(b-c/d)*e轉換成字尾表示式後為
abcd/-e*+
其運算次序為:t1=cd/; t2=bt1-; t3=t2e*; t4=at3+。
基於字尾表示式的兩個特點,計算過程如下:計算時只要從左到右依次掃瞄字尾表示式的各個
單詞,當讀到的單詞為運算子時,就對該運算他會前兩個運算元進施以此運算所代表的操作,然後將結果t插入到字尾表示式中再重複上面的操作。
根據以上的講解,可初步地列出實現的步驟如下: 1.
把中綴表示式的字元中提取出一系列表示式單詞; 2.
把中綴表示式單詞系列轉換成字尾表示式單詞系列; 3.
對字尾表示式詞系列依次進行計算。
下面依次對各個步驟進行講解。
要提取表示式單詞,
首先要定義乙個單詞的類,判斷該字串是否是數字還是運算子
**如下
/**
* 判斷當前字元或字串是否是數字
* * @param str
* @return
*/public static boolean isnumber(string str)
將算式表示式轉換成運算元和運算子,放入鍊錶中
/**
* 分析四則運算表示式,將數字與運算子進行分解
*/public static listparse(string exp) else
explist.add(tempchar);
tempstr = "";
}} if (!tempstr.equals(""))
return explist;
}
中綴表示式轉換成字尾表示式的演算法步驟:(1).設定乙個堆疊s,初始時將棧頂元素設定為#。(2).順序讀入中綴表示式,當讀到的單詞為運算元時將其加入到線性表l, 並接著讀下乙個單詞。(3).令x1為當前棧頂運算子的變數,x2為當前掃瞄讀到的運算子的變數,當順序從中綴表示式中讀入的單詞為運算子時就賦予x2;然後比較x1與x2的優先順序,若優先順序x1>x2,將x1從s中出棧,並加入l中,接著比較新的棧頂運算子x1與x2的優先順序;若優先順序x1,將x2入棧s,接著讀下乙個單詞;若優先順序x1=x2且x1為」(
」而x2為」)
」,將x1出棧,接著讀下乙個單詞;若優先順序x1=x2且x1為」#
」而x2為」#
」,演算法結束。
各運算子優先順序關係表
x2 x1 +
- ×÷ (
) #+
>
>
<
<
<
>
> -
>
>
<
<
<
>
> ×
>
>
>
>
<
>
> ÷
>
>
>
>
<
>
> (
<
<
<
<
< =
$ )>
>
>
> $
>
> #
<
<
<
<
< $
= 表中x1為+或-,x2為*或/時,優先順序x1,滿足中綴表示式規則
1.先乘除後加減;
x1為+、-、*或/,x2為(或/時,優先順序x1,滿足中綴表示式規則
2.先括號內後括號外;
當x1的運算子x2的運算子同級別時,優先順序x1=x2,滿足中綴表示式規則
3.同級別時先左後右。
出現表中的$表示中綴表示式語法出錯。
中綴表示式轉換成字尾的過程步驟
中序表示式 堆疊
輸出 1
a+(b-c/d)*e# #
2 +(b-c/d)*e#
# a
3 (b-c/d)*e#
#+ a
4b-c/d)*e#
#+( a
5-c/d)*e#
#+( ab
6c/d)*e#
#+(- ab
7/d)*e#
#+(-
abc 8
d)*e#
#+(-/
abc 9
)*e#
#+(-/
abcd 10
*e#
#+(-
abcd/ 11
*e#
#+(abcd- 12
*e#
#+abcd- 13
e# #+*
abcd- 14
# #+*
abcd-e 15
# #+
abcd-e* 16
# #abcd-e*+
/**
* 將分解後的四則運算列表構建成逆波蘭表示式列表
*/public static listcreaterpn(listexplist) else else if (operatorutils.isparenthesesend(c)) else
}} else else
}// 將當前字串直接壓棧
stack.push(c);}}
}} // 如果棧不為空,則將棧中所有元素出棧放到逆波蘭鍊錶的最後
while (!stack.isempty())
return rpnlist;
}
參考位址
四則運算計算器
今天做個帶視窗的c 四則運算計算器 輸入中綴表示式 自然表示式 可以用list來放 先把它變成字尾表示式 逆波蘭表示式 用乙個棧放運算子,另乙個棧放字尾表示式 運算子優先順序 1 2 3 4 從左到右遍歷中綴表示式 計算字尾表示式 從左到右掃瞄字尾表示式,如果是數字,放入數字棧。如果是符號,從數字棧...
四則運算計算程式 初步
這學期的軟體工程課上,老師給我們布置了一道題目 編寫乙個程式 它可以讀入乙個寫有很多數學算式的txt文件。對於每一條算式,先請使用者輸入算式答案,再由程式自動計算算式答案。若使用者輸入正確,則提示正確,若輸入錯誤,則提示錯誤和顯示正確答案。要求算式含有真分數和假分數。拿到這道題目我首先想到的是原來資...
表示式計算 四則運算(有括號)的計算
問題描述 輸入乙個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。輸入格式 輸入一行,包含乙個表示式。輸出格式 輸出這個表示式的值。樣例輸入 1 2 3 4 5 樣例輸出 4資料規模和約定 表示式長度不超過100,表示式運算合法且運算過程都在int內進行。includeusing n...