版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、前綴、中綴、后綴表達(dá)式它們都是對表達(dá)式的記法,因此也被稱為前綴記法、中綴記法和后綴記法。它們之間的區(qū)別在于運(yùn)算符相對與操作數(shù)的位置不同:前綴表達(dá)式的運(yùn)算符位于與其相關(guān)的操作數(shù)之前;中綴和后綴同理。舉例:(3 + 4) × 5 - 6 就是中綴表達(dá)式- × + 3 4 5 6 前綴表達(dá)式3 4 + 5 × 6 - 后綴表達(dá)式中綴表達(dá)式(中綴記法)中綴表達(dá)式是一種通用的算術(shù)或邏輯公式表示方法,操作符以中綴形式處于操作數(shù)的中間。中綴表達(dá)式是人們常用的算術(shù)表示方法。雖然人的大腦很容易理解與分析中綴表達(dá)式,但對計算機(jī)來說中綴表達(dá)式卻是很復(fù)雜的,因此計算表
2、達(dá)式的值時,通常需要先將中綴表達(dá)式轉(zhuǎn)換為前綴或后綴表達(dá)式,然后再進(jìn)行求值。對計算機(jī)來說,計算前綴或后綴表達(dá)式的值非常簡單。前綴表達(dá)式(前綴記法、波蘭式)前綴表達(dá)式的運(yùn)算符位于操作數(shù)之前。前綴表達(dá)式的計算機(jī)求值:從右至左掃描表達(dá)式,遇到數(shù)字時,將數(shù)字壓入堆棧,遇到運(yùn)算符時,彈出棧頂?shù)膬蓚€數(shù),用運(yùn)算符對它們做相應(yīng)的計算(棧頂元素 op 次頂元素),并將結(jié)果入棧;重復(fù)上述過程直到表達(dá)式最左端,最后運(yùn)算得出的值即為表達(dá)式的結(jié)果。例如前綴表達(dá)式“- × + 3 4 5 6”:(1) 從右至左掃描,將6、5、4、3壓入堆棧;(2) 遇到+運(yùn)算符,因此彈出3和4(3為棧頂元素,4為次頂元素,注意與
3、后綴表達(dá)式做比較),計算出3+4的值,得7,再將7入棧;(3) 接下來是×運(yùn)算符,因此彈出7和5,計算出7×5=35,將35入棧;(4) 最后是-運(yùn)算符,計算出35-6的值,即29,由此得出最終結(jié)果??梢钥闯?,用計算機(jī)計算前綴表達(dá)式的值是很容易的。將中綴表達(dá)式轉(zhuǎn)換為前綴表達(dá)式:遵循以下步驟:(1) 初始化兩個棧:運(yùn)算符棧S1和儲存中間結(jié)果的棧S2;(2) 從右至左掃描中綴表達(dá)式;(3) 遇到操作數(shù)時,將其壓入S2;(4) 遇到運(yùn)算符時,比較其與S1棧頂運(yùn)算符的優(yōu)先級:(4-1) 如果S1為空,或棧頂運(yùn)算符為右括號“)”,則直接將此運(yùn)算符入棧;(4-2) 否則,若優(yōu)先級比棧頂
4、運(yùn)算符的較高或相等,也將運(yùn)算符壓入S1;(4-3) 否則,將S1棧頂?shù)倪\(yùn)算符彈出并壓入到S2中,再次轉(zhuǎn)到(4-1)與S1中新的棧頂運(yùn)算符相比較;(5) 遇到括號時:(5-1) 如果是右括號“)”,則直接壓入S1;(5-2) 如果是左括號“(”,則依次彈出S1棧頂?shù)倪\(yùn)算符,并壓入S2,直到遇到右括號為止,此時將這一對括號丟棄;(6) 重復(fù)步驟(2)至(5),直到表達(dá)式的最左邊;(7) 將S1中剩余的運(yùn)算符依次彈出并壓入S2;(8) 依次彈出S2中的元素并輸出,結(jié)果即為中綴表達(dá)式對應(yīng)的前綴表達(dá)式。例如,將中綴表達(dá)式“1+(2+3)×4)-5”轉(zhuǎn)換為前綴表達(dá)式的過程如下:掃描到的元素S2(
5、棧底->棧頂)S1 (棧底->棧頂)說明55空數(shù)字,直接入棧-5-S1為空,運(yùn)算符直接入棧)5- )右括號直接入棧45 4- )數(shù)字直接入棧×5 4- ) ×S1棧頂是右括號,直接入棧)5 4- ) × )右括號直接入棧35 4 3- ) × )數(shù)字+5 4 3- ) × ) +S1棧頂是右括號,直接入棧25 4 3 2- ) × ) +數(shù)字(5 4 3 2 +- ) ×左括號,彈出運(yùn)算符直至遇到右括號(5 4 3 2 + ×-同上+5 4 3 2 + ×- +優(yōu)先級與-相同,入棧15 4 3
6、 2 + × 1- +數(shù)字到達(dá)最左端5 4 3 2 + × 1 + -空S1中剩余的運(yùn)算符因此結(jié)果為“- + 1 × + 2 3 4 5”。后綴表達(dá)式(后綴記法、逆波蘭式)后綴表達(dá)式與前綴表達(dá)式類似,只是運(yùn)算符位于操作數(shù)之后。后綴表達(dá)式的計算機(jī)求值:與前綴表達(dá)式類似,只是順序是從左至右:從左至右掃描表達(dá)式,遇到數(shù)字時,將數(shù)字壓入堆棧,遇到運(yùn)算符時,彈出棧頂?shù)膬蓚€數(shù),用運(yùn)算符對它們做相應(yīng)的計算(次頂元素 op 棧頂元素),并將結(jié)果入棧;重復(fù)上述過程直到表達(dá)式最右端,最后運(yùn)算得出的值即為表達(dá)式的結(jié)果。例如后綴表達(dá)式“3 4 + 5 × 6 -”:(
7、1) 從左至右掃描,將3和4壓入堆棧;(2) 遇到+運(yùn)算符,因此彈出4和3(4為棧頂元素,3為次頂元素,注意與前綴表達(dá)式做比較),計算出3+4的值,得7,再將7入棧;(3) 將5入棧;(4) 接下來是×運(yùn)算符,因此彈出5和7,計算出7×5=35,將35入棧;(5) 將6入棧;(6) 最后是-運(yùn)算符,計算出35-6的值,即29,由此得出最終結(jié)果。將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式:與轉(zhuǎn)換為前綴表達(dá)式相似,遵循以下步驟:(1) 初始化兩個棧:運(yùn)算符棧S1和儲存中間結(jié)果的棧S2;(2) 從左至右掃描中綴表達(dá)式;(3) 遇到操作數(shù)時,將其壓入S2;(4) 遇到運(yùn)算符時,比較其與
8、S1棧頂運(yùn)算符的優(yōu)先級:(4-1) 如果S1為空,或棧頂運(yùn)算符為左括號“(”,則直接將此運(yùn)算符入棧;(4-2) 否則,若優(yōu)先級比棧頂運(yùn)算符的高,也將運(yùn)算符壓入S1(注意轉(zhuǎn)換為前綴表達(dá)式時是優(yōu)先級較高或相同,而這里則不包括相同的情況);(4-3) 否則,將S1棧頂?shù)倪\(yùn)算符彈出并壓入到S2中,再次轉(zhuǎn)到(4-1)與S1中新的棧頂運(yùn)算符相比較;(5) 遇到括號時:(5-1) 如果是左括號“(”,則直接壓入S1;(5-2) 如果是右括號“)”,則依次彈出S1棧頂?shù)倪\(yùn)算符,并壓入S2,直到遇到左括號為止,此時將這一對括號丟棄;(6) 重復(fù)步驟(2)至(5),直到表達(dá)式的最右邊;(7) 將S1中剩余的運(yùn)算符
9、依次彈出并壓入S2;(8) 依次彈出S2中的元素并輸出,結(jié)果的逆序即為中綴表達(dá)式對應(yīng)的后綴表達(dá)式(轉(zhuǎn)換為前綴表達(dá)式時不用逆序)。例如,將中綴表達(dá)式“1+(2+3)×4)-5”轉(zhuǎn)換為后綴表達(dá)式的過程如下:掃描到的元素S2(棧底->棧頂)S1 (棧底->棧頂)說明11空數(shù)字,直接入棧+1+S1為空,運(yùn)算符直接入棧(1+ (左括號,直接入棧(1+ ( (同上21 2+ ( (數(shù)字+1 2+ ( ( +S1棧頂為左括號,運(yùn)算符直接入棧31 2 3+ ( ( +數(shù)字)1 2 3 + (右括號,彈出運(yùn)算符直至遇到左括號×1 2 3 + ( ×S1棧頂為左括號,運(yùn)算
10、符直接入棧41 2 3 + 4+ ( ×數(shù)字)1 2 3 + 4 ×+右括號,彈出運(yùn)算符直至遇到左括號-1 2 3 + 4 × +-與+優(yōu)先級相同,因此彈出+,再壓入-51 2 3 + 4 × + 5-數(shù)字到達(dá)最右端1 2 3 + 4 × + 5 -空S1中剩余的運(yùn)算符因此結(jié)果為“1 2 3 + 4 × + 5 -”(注意需要逆序輸出)。編寫Java程序?qū)⒁粋€中綴表達(dá)式轉(zhuǎn)換為前綴表達(dá)式和后綴表達(dá)式,并計算表達(dá)式的值。其中的toPolishNotation()方法將中綴表達(dá)式轉(zhuǎn)換為前綴表達(dá)式(波蘭式)、toReversePolishNo
11、tation()方法則用于將中綴表達(dá)式轉(zhuǎn)換為后綴表達(dá)式(逆波蘭式):注:(1) 程序很長且注釋比較少,但如果將上面的理論內(nèi)容弄懂之后再將程序編譯并運(yùn)行起來,還是比較容易理解的。有耐心的話可以研究一下。(2) 此程序是筆者為了說明上述概念而編寫,僅做了簡單的測試,不保證其中沒有Bug,因此不要將其用于除研究之外的其他場合。java view plain copy1. package qmk.simple_test; 2. import java.util.Scanner; 3. import java.
12、util.Stack; 4. /* 5. * Example of converting an infix-expression to 6. * Polish Notation (PN) or Reverse Polish Notation (RPN). 7. * Written in 2011-8-25 8. *
13、160;author QiaoMingkui 9. */ 10. public class Calculator 11. public static final String USAGE = "= usage =n" 12.
14、 + "input the expressions, and then the program " 13. + "will calculate them and show the re
15、sult.n" 14. + "input 'bye' to exit.n" 15. /* 16. * param args 17.
16、 */ 18. public static void main(String args) 19. System.out.println(USAGE); 20.
17、; Scanner scanner = new Scanner(System.in); 21. String input = "" 22.
18、160; final String CLOSE_MARK = "bye" 23. System.out.println("input an expression:"); 24.
19、160; input = scanner.nextLine(); 25. while (input.length() != 0 26.
20、 && !CLOSE_MARK.equals(input) 27. System.out.print("Polish Notation (PN):"); 28.
21、60; try 29. toPolishNotation(input); 30.
22、0; catch (NumberFormatException e) 31. &
23、#160; System.out.println("ninput error, not a number."); 32. catch (IllegalArgumentException e) 33. &
24、#160; System.out.println("ninput error:" + e.getMessage(); 34.
25、0; catch (Exception e) 35. System.out.println("ninput error, invalid
26、;expression."); 36. 37. System.out.print("Reverse
27、160;Polish Notation (RPN):"); 38. try 39.
28、; toReversePolishNotation(input); 40. catch (NumberFormatException e) 41.
29、60; System.out.println("ninput error, not a number."); 42.
30、60; catch (IllegalArgumentException e) 43. System.out.println("ninput error:" + e.getMessage(
31、); 44. catch (Exception e) 45.
32、60; System.out.println("ninput error, invalid expression."); 46. 47.
33、0; System.out.println("input a new expression:"); 48. input = scanner.nextLine();
34、49. 50. System.out.println("program exits"); 51. 52.
35、; /* 53. * parse the expression , and calculate it. 54. * param input 55. * throws Ille
36、galArgumentException 56. * throws NumberFormatException 57. */ 58. private static void toPolishNotation(String input)
37、59. throws IllegalArgumentException, NumberFormatException 60. int len = input
38、.length(); 61. char c, tempChar; 62. Stack<Character> s1 = new Stack<Character>();
39、0;63. Stack<Double> s2 = new Stack<Double>(); 64. Stack<Object> expression = new Stack&
40、lt;Object>(); 65. double number; 66. int lastIndex = -1; 67.
41、60; for (int i=len-1; i>=0; -i) 68. c = input.charAt(i); 69.
42、; if (Character.isDigit(c) 70. lastIndex = readDoubleRevers
43、e(input, i); 71. number = Double.parseDouble(input.substring(lastIndex, i+1); 72.
44、160; s2.push(number); 73. i =
45、0;lastIndex; 74. if (int) number = number) 75. &
46、#160; expression.push(int) number); 76.
47、; else 77. expression.push(number); 78.
48、; else if (isOperator(c) 79. while (!s1.isEmpty() 80.
49、 && s1.peek() != ')' 81.
50、 && priorityCompare(c, s1.peek() < 0) 82. &
51、#160; expression.push(s1.peek(); 83. &
52、#160; s2.push(calc(s2.pop(), s2.pop(), s1.pop(); 84.
53、; 85. s1.push(c); 86.
54、0;else if (c = ')') 87. s1.push(c); 88.
55、 else if (c = '(') 89. while (tempChar=s1.pop()
56、!= ')') 90. expression.push(tempChar); 91.
57、 s2.push(calc(s2.pop(), s2.pop(), tempChar); 92.
58、60; if (s1.isEmpty() 93.
59、160; throw new IllegalArgumentException( 94. &
60、#160; "bracket dosen't match, missing right bracket ')'."); 95.
61、 96. 97.
62、0; else if (c = ' ') 98. / ignore 99.
63、 else 100. throw new
64、 IllegalArgumentException( 101. "wrong character '
65、;" + c + "'"); 102. 103. 104.
66、0; while (!s1.isEmpty() 105. tempChar = s1.pop(); 106.
67、; expression.push(tempChar); 107. s2.push(calc(s2.pop(), s2.pop(), tempChar); 108.
68、 109. while (!expression.isEmpty() 110.
69、; System.out.print(expression.pop() + " "); 111. 112. double result = s2.pop();
70、60; 113. if (!s2.isEmpty() 114. throw new IllegalArgumentException("input is
71、60;a wrong expression."); 115. System.out.println(); 116. if (int) result = result) 117.
72、 System.out.println("the result is " + (int) result); 118. else
73、 119. System.out.println("the result is " + result); 120. 121.
74、 /* 122. * parse the expression, and calculate it. 123. * param input 124. * throws IllegalArgumentExcep
75、tion 125. * throws NumberFormatException 126. */ 127. private static void toReversePolishNotation(String input) 128. &
76、#160; throws IllegalArgumentException, NumberFormatException 129. int len = input.len
77、gth(); 130. char c, tempChar; 131. Stack<Character> s1 = new Stack<Character>();
78、132. Stack<Double> s2 = new Stack<Double>(); 133. double number; 134.
79、60; int lastIndex = -1; 135. for (int i=0; i<len; +i) 136.
80、160; c = input.charAt(i); 137. if (Character.isDigit(c) | c = '.') 138.
81、160; lastIndex = readDouble(input, i); 139.
82、60; number = Double.parseDouble(input.substring(i, lastIndex); 140. s2.push(number);
83、; 141. i = lastIndex - 1; 142.
84、; if (int) number = number) 143. Sys
85、tem.out.print(int) number + " "); 144. else 145. &
86、#160; System.out.print(number + " "); 146.
87、 else if (isOperator(c) 147. while (!s1.isEmpty() 148.
88、; && s1.peek() != '(' 149.
89、0; && priorityCompare(c, s1.peek() <= 0) 150.
90、60; System.out.print(s1.peek() + " "); 151.
91、; double num1 = s2.pop(); 152.
92、0; double num2 = s2.pop(); 153. s2.push(calc(num2, num1, s1.pop(); &
93、#160;154. 155.
94、60; s1.push(c); 156. else if (c = '(') 157.
95、60; s1.push(c); 158. else if (c = ')') 159.
96、60; while (tempChar=s1.pop() != '(') 160.
97、60; System.out.print(tempChar + " "); 161.
98、 double num1 = s2.pop(); 162. double num2 =
99、s2.pop(); 163. s2.push(calc(num2, num1, tempChar); 164.
100、160; if (s1.isEmpty() 165.
101、 throw new IllegalArgumentException( 166.
102、0; "bracket dosen't match, missing left bracket '('."); 167.
103、60; 168. 169.
104、 else if (c = ' ') 170.
105、0; / ignore 171. else 172. &
106、#160; throw new IllegalArgumentException( 173.
107、; "wrong character '" + c + "'"); 174. 175.
108、160; 176. while (!s1.isEmpty() 177. tempChar = s1.pop
109、(); 178. System.out.print(tempChar + " "); 179. &
110、#160; double num1 = s2.pop(); 180. double num2 = s2.pop(); 181.
111、; s2.push(calc(num2, num1, tempChar); 182. 183. double result = s2.pop();
112、 184. if (!s2.isEmpty() 185. throw new IllegalArgumentException("input is
113、 a wrong expression."); 186. System.out.println(); 187. if (int) result = result) 1
114、88. System.out.println("the result is " + (int) result); 189. else
115、60; 190. System.out.println("the result is " + result); 191. 192.
116、60; /* 193. * calculate the two number with the operation. 194. * param num1 195. * param num2
117、;196. * param op 197. * return 198. * throws IllegalArgumentException 199. */ 200
118、. private static double calc(double num1, double num2, char op) 201. throws IllegalArgumentException
119、 202. switch (op) 203. case '+': 204. &
120、#160; return num1 + num2; 205. case '-': 206. &
121、#160; return num1 - num2; 207. case '*': 208. return&
122、#160;num1 * num2; 209. case '/': 210. if (num2 = 0) thr
123、ow new IllegalArgumentException("divisor can't be 0."); 211. return num1 / num2; 212.
124、 default: 213. return 0; / will never catch up here 214. &
125、#160; 215. 216. /* 217. * compare the two operations' priority. 218. &
126、#160; * param c 219. * param peek 220. * return 221. */ 222. private st
127、atic int priorityCompare(char op1, char op2) 223. switch (op1) 224. case '+':
128、160;case '-': 225. return (op2 = '*' | op2 = '/' ? -1 : 0); 226.
129、60; case '*': case '/': 227. return (op2 = '+' | op2 = '
130、-' ? 1 : 0); 228. 229. return 1; 230. 231.
131、160; /* 232. * read the next number (reverse) 233. * param input 234. * param start
132、160;235. * return 236. * throws IllegalArgumentException 237. */ 238. private static int
133、0;readDoubleReverse(String input, int start) 239. throws IllegalArgumentException 240.
134、60; int dotIndex = -1; 241. char c; 242. for (int i=start; i>=0; -i)
135、 243. c = input.charAt(i); 244. if (c =
136、9;.') 245. if (dotIndex != -1) 246. &
137、#160; throw new IllegalArgumentException( 247.
138、; "there have more than 1 dots in the number."); 248.
139、 else 249. dotIndex = i; 250.
140、; else if (!Character.isDigit(c) 251.
141、160;return i + 1; 252. else if (i = 0) 253. &
142、#160; return 0; 254. 255. &
143、#160;256. throw new IllegalArgumentException("not a number."); 257. 258. 259. &
144、#160; /* 260. * read the next number 261. * param input 262. * param start 263.
145、; * return 264. * throws IllegalArgumentException 265. */ 266. private static int readDouble(String i
146、nput, int start) 267. throws IllegalArgumentException 268. int len = input.length(); 269.
147、60; int dotIndex = -1; 270. char c; 271. for (int i=start; i<
148、len; +i) 272. c = input.charAt(i); 273. i
149、f (c = '.') 274. if (dotIndex != -1) 275.
150、 throw new IllegalArgumentException( 276.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度智能安防系統(tǒng)設(shè)備維修與升級合同3篇
- 二零二五年度鄉(xiāng)村旅游開發(fā)農(nóng)村房屋買賣合同協(xié)議書2篇
- 2025年度企業(yè)公務(wù)車借用與車輛保險理賠協(xié)議范本3篇
- 二零二五年度農(nóng)機(jī)維修配件進(jìn)出口貿(mào)易合同模板3篇
- 二零二五年度農(nóng)村宅基地房屋買賣及農(nóng)村社會保障體系建設(shè)合同
- 2025年度農(nóng)村農(nóng)業(yè)勞務(wù)用工合同范本(含勞動爭議調(diào)解)
- 二零二五年度新能源實(shí)驗(yàn)室儲能技術(shù)研究合同3篇
- 二零二五年度汽車維修兼職技師雇傭合同3篇
- 2025年度XX能源公司二零二五年度綠色貸款合同3篇
- 2025年度商業(yè)綜合體寫字樓租賃管理服務(wù)協(xié)議3篇
- 四川省成都市龍泉驛區(qū)2023-2024學(xué)年三年級數(shù)學(xué)第一學(xué)期期末監(jiān)測試題含答案
- 鍋爐控制器modbus協(xié)議支持說明
- 粉末涂料有限公司危廢庫安全風(fēng)險分級管控清單
- 750更換齒輪箱作業(yè)指導(dǎo)書
- GB/T 20706-2023可可粉質(zhì)量要求
- 安全生產(chǎn)信息管理制度全
- 世界主要國家洲別、名稱、首都、代碼、區(qū)號、時差匯總表
- 2023學(xué)年廣東省廣州市越秀區(qū)鐵一中學(xué)九年級(上)物理期末試題及答案解析
- 《報告文學(xué)研究》(07562)自考考試復(fù)習(xí)題庫(含答案)
- 電源日常點(diǎn)檢記錄表
- 人教版小學(xué)三年級語文上冊期末測試卷.及答題卡2
評論
0/150
提交評論