发现了大学时候写的计算器小程序,还有个图形界面,能够图形化展示表达式语法树,哈哈;)
只有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