發現了大學時候寫的計算器小程序,還有個圖形界面,能夠圖形化展示表達式語法樹,哈哈;)
只有200行Java代碼,不但能夠計算加減乘除,還能夠匹配小括號~
代碼點評:
從樸素的界面配色到簡單易懂錯誤提示,無不體現了“用戶體驗”至上的設計理念;代碼異常處理全面合理、滴水不漏,代碼縮進優雅大方,變量命名直觀易懂;再結合長度適中簡單明了的注釋,程序整體給人一種清新脫俗之感。背后不難看出作者對學習的熱愛以及對設計的苛求,工匠精神可見一斑,真可謂是大學數據結構學以致用的典范!
實現代碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.TextField; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Stack; import javax.swing.JFrame; /** * 圖形界面的計算器程序,只能計算加減乘除, * 算式中可以有小括號。數字可以是小數 */ public class CalcGUI extends JFrame{ private static final long serialVersionUID = 1L; private TreeNode resultTree; private String textFieldString; private boolean calcSuccess = true ; private char ops[][] = { { '>' , '>' , '<' , '<' , '<' , '>' , '>' }, { '>' , '>' , '<' , '<' , '<' , '>' , '>' }, { '>' , '>' , '>' , '>' , '<' , '>' , '>' }, { '>' , '>' , '>' , '>' , '<' , '>' , '>' }, { '<' , '<' , '<' , '<' , '<' , '=' , 'E' }, { 'E' , 'E' , 'E' , 'E' , 'E' , 'E' , 'E' }, { '<' , '<' , '<' , '<' , '<' , 'E' , '=' }, }; Stack<TreeNode> nodesStack = new Stack<TreeNode>(); Stack<Character> opsStack = new Stack<Character>(); publicstaticvoidmain(String[] args) { CalcGUI gui = new CalcGUI(); gui.userGUI(); } publicvoiduserGUI(){ this .setLayout( new BorderLayout()); TextField tf = new TextField( "請輸入表達式,按Enter開始計算~" , 40 ); tf.selectAll(); tf.getText(); tf.addKeyListener( new KeyAdapter(){ publicvoidkeyPressed(KeyEvent e){ if (e.getKeyCode() == KeyEvent.VK_ENTER){ textFieldString = ((TextField)e.getComponent()).getText(); calcSuccess = true ; resultTree = null ; try { resultTree = calc(textFieldString + "#" ); } catch (Exception e1){ calcSuccess = false ; } CalcGUI. this .repaint(); } } }); this .add(tf, BorderLayout.NORTH); this .setSize( 500 , 500 ); this .setTitle( "calc GUI" ); this .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this .setResizable( true ); this .setVisible( true ); } private int levelHeight = 60 ; private int diameter = 25 ; publicvoidpaint(Graphics g){ super .paint(g); if (calcSuccess){ if (resultTree != null ){ g.drawString( "計算結果為:" + resultTree.value, 10 , 80 ); int rootBeginX = this .getWidth() / 2 ; int rootBeginY = 100 ; Point p = new Point(rootBeginX, rootBeginY); drawTree(g, resultTree, p, this .getWidth() / 2 - 20 , p); } } else { g.setColor(Color.RED); g.drawString( "表達式語法有誤!" , 10 , 80 ); } } privatevoiddrawCircle(Graphics g, Point p, int r){ g.drawOval(p.x - r, p.y - r, r * 2 , r * 2 ); } privatevoiddrawTree(Graphics g, TreeNode node, Point pme, int width, Point pfather){ if (node == null ) return ; // System.out.println("in drawTree, node.value=" + node.value + ",node.op=" + node.op); g.setColor(Color.GREEN); this .drawCircle(g, pme, diameter / 2 ); g.drawLine(pme.x, pme.y, pfather.x, pfather.y); if (node.op != 'E' ){ g.setColor(Color.BLACK); g.drawString(String.valueOf(node.op), pme.x, pme.y); } else { g.setColor(Color.BLACK); g.drawString(String.valueOf(node.value), pme.x - diameter / 2 , pme.y); } drawTree(g, node.lft, new Point(pme.x - width / 2 , pme.y + levelHeight), width / 2 , pme); drawTree(g, node.rt, new Point(pme.x + width / 2 , pme.y + levelHeight), width / 2 , pme); } public TreeNode calc(String inStr) throws Exception{ opsStack.push( '#' ); StringBuilder buf = new StringBuilder(); int i = 0 ; while (i < inStr.length()){ if (Character.isDigit(inStr.charAt(i)) || inStr.charAt(i) == '.' ){ // number buf.delete( 0 , buf.length()); while (i < inStr.length() && (Character.isDigit(inStr.charAt(i)) || inStr.charAt(i) == '.' )) buf.append(inStr.charAt(i++)); Double number = Double.parseDouble(buf.toString()); nodesStack.push( new TreeNode(number)); } else if (inStr.charAt(i) == ' ' ){ i++; continue ; } else { // operation char op = inStr.charAt(i); int subNew = getSub(op); boolean goOn = true ; while (goOn){ if (opsStack.isEmpty()) throw new Exception( "運算符太少!" ); char opFormer = opsStack.peek(); int subFormer = getSub(opFormer); switch (ops[subFormer][subNew]){ case '=' : goOn = false ; opsStack.pop(); break ; case '<' : goOn = false ; opsStack.push(op); break ; case '>' : goOn = true ; TreeNode n1 = nodesStack.pop(); TreeNode n0 = nodesStack.pop(); double rs = doOperate(n0.value, n1.value, opFormer); nodesStack.push( new TreeNode(rs, opFormer, n0, n1)); opsStack.pop(); break ; default : throw new Exception( "沒有匹配的操作符:" + op); } } i++; } } return nodesStack.pop(); } privatedoubledoOperate( double n0, double n1, char op) throws Exception{ switch (op){ case '+' : return n0 + n1; case '-' : return n0 - n1; case '*' : return n0 * n1; case '/' : return n0 / n1; default : throw new Exception( "非法操作符:" + op); } } privateintgetSub( char c){ switch (c){ case '+' : return 0 ; case '-' : return 1 ; case '*' : return 2 ; case '/' : return 3 ; case '(' : return 4 ; case ')' : return 5 ; case '#' : return 6 ; default : return - 1 ; } } } class TreeNode{ public double value; public char op = 'E' ; public TreeNode lft; public TreeNode rt; public TreeNode( double value){ this .value = value; } public TreeNode( double value, char op, TreeNode lft, TreeNode rt){ this .value = value; this .op = op; this .lft = lft; this .rt = rt; } StringBuilder buf = new StringBuilder(); public String toString(){ out( this ); return buf.toString(); } privatevoidout(TreeNode node){ if (node == null ) return ; out(node.lft); if (node.op != 'E' ) buf.append(node.op); else buf.append(node.value); out(node.rt); } } |
總結
以上所述是小編給大家介紹的200行Java代碼編寫一個計算器程序,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家的支持!
原文鏈接:http://www.linuxidc.com/Linux/2017-12/149689.htm