服务器之家

服务器之家 > 正文

200行Java代码编写一个计算器程序

时间:2021-03-10 13:26     来源/作者:Java教程网

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

只有200行Java代码,不但能够计算加减乘除,还能够匹配小括号~

代码点评:

从朴素的界面配色到简单易懂错误提示,无不体现了“用户体验”至上的设计理念;代码异常处理全面合理、滴水不漏,代码缩进优雅大方,变量命名直观易懂;再结合长度适中简单明了的注释,程序整体给人一种清新脱俗之感。背后不难看出作者对学习的热爱以及对设计的苛求,工匠精神可见一斑,真可谓是大学数据结构学以致用的典范!

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

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部