200行Java代碼編寫一個(gè)計(jì)算器程序
發(fā)現(xiàn)了大學(xué)時(shí)候?qū)懙挠?jì)算器小程序,還有個(gè)圖形界面,能夠圖形化展示表達(dá)式語(yǔ)法樹,哈哈;)
只有200行Java代碼,不但能夠計(jì)算加減乘除,還能夠匹配小括號(hào)~
代碼點(diǎn)評(píng):
從樸素的界面配色到簡(jiǎn)單易懂錯(cuò)誤提示,無(wú)不體現(xiàn)了“用戶體驗(yàn)”至上的設(shè)計(jì)理念;代碼異常處理全面合理、滴水不漏,代碼縮進(jìn)優(yōu)雅大方,變量命名直觀易懂;再結(jié)合長(zhǎng)度適中簡(jiǎn)單明了的注釋,程序整體給人一種清新脫俗之感。背后不難看出作者對(duì)學(xué)習(xí)的熱愛以及對(duì)設(shè)計(jì)的苛求,工匠精神可見一斑,真可謂是大學(xué)數(shù)據(jù)結(jié)構(gòu)學(xué)以致用的典范!
實(shí)現(xiàn)代碼如下所示:
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;
/** * 圖形界面的計(jì)算器程序,只能計(jì)算加減乘除, * 算式中可以有小括號(hào)。數(shù)字可以是小數(shù) */
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("請(qǐng)輸入表達(dá)式,按Enter開始計(jì)算~", 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("計(jì)算結(jié)果為:" + 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("表達(dá)式語(yǔ)法有誤!", 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("運(yùn)算符太少!");
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);
}
}
總結(jié)
以上所述是小編給大家介紹的200行Java代碼編寫一個(gè)計(jì)算器程序,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家的支持!
- Java簡(jiǎn)易計(jì)算器程序設(shè)計(jì)
- java實(shí)現(xiàn)簡(jiǎn)易計(jì)算器功能
- Java實(shí)現(xiàn)計(jì)算器的代碼
- java 簡(jiǎn)單的計(jì)算器程序?qū)嵗a
- java實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器類實(shí)例
- java實(shí)現(xiàn)計(jì)算器功能
- 用Java實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
- Java編寫簡(jiǎn)單計(jì)算器的完整實(shí)現(xiàn)過程
- Java編寫計(jì)算器的常見方法實(shí)例總結(jié)
- 用Java打造簡(jiǎn)易計(jì)算器的實(shí)現(xiàn)步驟
相關(guān)文章
mybatis二級(jí)緩存的實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了mybatis二級(jí)緩存的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
關(guān)于Controller層和Service層的類報(bào)錯(cuò)問題及解決方案
這篇文章主要介紹了關(guān)于Controller層和Service層的類報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
關(guān)于springcloud報(bào)錯(cuò)報(bào)UnsatisfiedDependencyException的問題
這篇文章主要介紹了關(guān)于springcloud報(bào)錯(cuò)報(bào)UnsatisfiedDependencyException的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
java如何根據(jù)用戶請(qǐng)求獲取ip地址并解析省市信息
根據(jù)當(dāng)前用戶本地IP地址,查詢IP地址庫(kù),獲取IP所在的省市信息,目前有多種方式實(shí)現(xiàn)該功能,這篇文章主要給大家介紹了關(guān)于java如何根據(jù)用戶請(qǐng)求獲取ip地址并解析省市信息的相關(guān)資料,需要的朋友可以參考下2023-12-12
SpringCloud Ribbon負(fù)載均衡代碼實(shí)例
這篇文章主要介紹了SpringCloud Ribbon負(fù)載均衡代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
struts中動(dòng)態(tài)方法調(diào)用使用通配符
這篇文章主要介紹了struts中動(dòng)態(tài)方法調(diào)用使用通配符的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09
Java數(shù)據(jù)結(jié)構(gòu)之鏈表的增刪查改詳解
在這篇文章中,小編將帶大家了解一下Java數(shù)據(jù)結(jié)構(gòu)中鏈表的增刪查改(以下結(jié)果均在IDEA中編譯)希望在方便自己復(fù)習(xí)的同時(shí)也能幫助到大家2022-09-09

