闲来无聊,一个月前学习一下java,就写了一个简单计算器,界面太挫,就不粘了,实现的功能就是支持带括号的表达式的计算,支持后退。
语言就是java,编译器Eclipse,中间用了一下数据结构中缀转后缀,通过后缀计算表达式,括号匹配,加减乘除用了一下简单工厂模式,对于启动的界面类,和工厂类,用了一下单例模式,中间有个分析类,中间缺少一个控制类,还是有些混乱,要不然就更加完美了,用简单工厂模式,主要是为了方便扩展功能,单例含义不能创建多个不同实例,总体来说还是有很多地方比较混乱,不多说了,还是复制一下代码吧:
程序启动入口:
package org.study.calculator;/** * main函数 程序入口 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class Enter{ public static void main(String[] args) { View view = View.getInstance(); view.start(); }}
界面显示类:
package org.study.calculator;import java.awt.BorderLayout;import java.awt.Container;import java.awt.Dimension;import java.awt.Font;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextField;/** * 主界面类 * * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class View extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; //本类的一个对象 private static View viewInstance = null; //button上的内容 private String[] btnName = { "C", "(", ")", "←", "1", "2", "3", "+", "4", "5", "6", "-", "7", "8", "9", "*", "0", ".", "=", "/" }; private JTextField jtf = new JTextField(); public JTextField getJtf() { return jtf; } public void setJtf(JTextField jtf) { this.jtf = jtf; } /** * 监听界面的按键 */ @Override public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("+") || e.getActionCommand().equals("-") || e.getActionCommand().equals("*") || e.getActionCommand().equals("/") || e.getActionCommand().equals("=")) { jtf.setText(jtf.getText() + " " + e.getActionCommand() + " "); } else if (e.getActionCommand().equals("(")) { jtf.setText(jtf.getText() + e.getActionCommand() + " "); } else if (e.getActionCommand().equals(")")) { jtf.setText(jtf.getText() + " " + e.getActionCommand()); } else if (e.getActionCommand().equals("C")) { jtf.setText(""); } else if (e.getActionCommand().equals("←")) { String str = jtf.getText(); if (str.charAt(str.length() - 1) == ')') { str = str.substring(0, str.length() - 1); jtf.setText(str); str = str.substring(0, str.length() - 1); jtf.setText(str); } else if (str.charAt(str.length() - 2) == '+' || str.charAt(str.length() - 2) == '-' || str.charAt(str.length() - 2) == '*' || str.charAt(str.length() - 2) == '/') { str = str.substring(0, str.length() - 1); str = str.substring(0, str.length() - 1); str = str.substring(0, str.length() - 1); jtf.setText(str); } else if (str.charAt(str.length() - 2) == '(') { str = str.substring(0, str.length() - 1); str = str.substring(0, str.length() - 1); jtf.setText(str); } else { str = str.substring(0, str.length() - 1); jtf.setText(str); } } else { jtf.setText(jtf.getText() + e.getActionCommand()); } if (e.getActionCommand().equals("=")) { double sum; Analysis result = new Analysis(jtf.getText()); if (result.judgeExpressionRight() == true) { sum = result.start(); jtf.setText(jtf.getText() + sum); } else { jtf.setText(jtf.getText() + "Input Error!"); } } } /** * 获得本类的一个实例对象 * @return */ public static View getInstance() { if (viewInstance == null) { viewInstance = new View(); } return viewInstance; } /** * 界面显示类 */ private View() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jtf.setHorizontalAlignment(JTextField.RIGHT); jtf.setFont(new Font("微软雅黑", Font.BOLD, 25)); System.out.println(jtf.getSize().height + " ** " + jtf.getSize().width); Container c = this.getContentPane(); JPanel jpl = new JPanel(); c.add(jtf, BorderLayout.NORTH); c.add(jpl, BorderLayout.CENTER); jpl.setLayout(new GridLayout(5, 4)); Font font = new Font("微软雅黑", Font.PLAIN, 24); JButton b = null; //初始化button for (int i = 0; i < btnName.length; i++) { b = new JButton(btnName[i]); b.setFont(font); b.addActionListener(this); jpl.add(b); } } public void start() { System.out.println("Starting TestMyButton..."); View mainFrame = new View(); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); mainFrame.setSize(300, 400); mainFrame.setTitle("LuJie"); mainFrame.setVisible(true); mainFrame.setLocation((screen.width) / 2, (screen.height) / 2); }}
分析类:
package org.study.calculator;import java.util.ArrayList;import java.util.List;import java.util.Stack;import org.study.father.Calculator;/** * 分析类 括号匹配 中缀转后缀 和 后缀计算结果 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class Analysis { private String midExpression; //中缀表达式 private String [] splitMid ; //中缀表达式分割之后 public String getMidExpression() { return midExpression; } public void setMidExpression(String midExpression) { this.midExpression = midExpression; } public Analysis(String midExpression){ this.midExpression = midExpression; System.out.println(midExpression); //start(); } /** * 判断表达式是否括号匹配(用栈) * @return */ public boolean judgeExpressionRight(){ splitMid = midExpression.split(" "); Stackstack = new Stack (); for(int i = 0; i < splitMid.length; i++){ if(splitMid[i].equals("(")){ stack.push("("); } if(splitMid[i].equals(")")){ if(stack.empty()){ return false; }else { stack.pop(); } } } if(stack.empty()){ return true; }else{ return false; } } /** * 计算表达式(利用后缀表达式) * @return */ public double start(){ double sum; CalculatorFactory calFac = CalculatorFactory.GetInstance(); Stack stack = new Stack (); System.out.println(splitMid.length); String [] endExpressionStr = midToEnd(splitMid); for(int i = 0; i < endExpressionStr.length; i++){ if(endExpressionStr[i].equals("+") || endExpressionStr[i].equals("-") || endExpressionStr[i].equals("*") || endExpressionStr[i].equals("/")){ double a = stack.peek(); stack.pop(); double b = stack.peek(); stack.pop(); if(endExpressionStr[i].equals("+")){ Calculator calculator = calFac.getCalculatorInstance("Addition"); sum = calculator.count(b, a); }else if(endExpressionStr[i].equals("-")){ Calculator calculator = calFac.getCalculatorInstance("SubStraction"); sum = calculator.count(b, a); }else if(endExpressionStr[i].equals("*")){ Calculator calculator = calFac.getCalculatorInstance("Multiplication"); sum = calculator.count(b, a); }else{ Calculator calculator = calFac.getCalculatorInstance("Division"); sum = calculator.count(b, a); } stack.push(sum); }else{ double f = Float.valueOf(endExpressionStr[i]); stack.push(f); } } sum = stack.pop(); return sum; } /** * 中缀表达式转后缀表达式 * @param splitMid 分割之后的中缀表达式 * @return */ public String [] midToEnd(String []splitMid){ List endExpressionStr = new ArrayList (); Stack stack = new Stack (); for(int i = 0; i < splitMid.length - 1; i++){ if("(".equals(splitMid[i])){ stack.push(splitMid[i]); }else if( "+".equals(splitMid[i]) || "-".equals(splitMid[i]) || "*".equals(splitMid[i]) || "/".equals(splitMid[i])){ if(!stack.empty()){ String s = stack.pop(); if(comparePrior(splitMid[i],s)){ stack.push(s); }else{ endExpressionStr.add(s); } } stack.push(splitMid[i]); }else if(")".equals(splitMid[i])){ while(!stack.empty()){ String s = stack.pop(); if(!"(".equals(s)){ endExpressionStr.add(s); }else{ break; } } }else{ endExpressionStr.add(splitMid[i]); } } while(!stack.empty()){ String s = stack.pop(); endExpressionStr.add(s); } return endExpressionStr.toArray(new String[0]); } /** * 比较操作符优先级 * @param operator1 * @param operator2 * @return */ public boolean comparePrior(String operator1, String operator2){ if("(".equals(operator2)){ return true; } if("*".equals(operator1) || "*".equals(operator1)){ if("+".equals(operator2) || "-".equals(operator2)){ return true; } } return false; }}
简单工厂开始了:
工厂类(对这个类还是用了一下单例):
package org.study.calculator;import org.study.father.Calculator;import org.study.son.Addition;import org.study.son.Division;import org.study.son.Multiplication;import org.study.son.SubStraction;/** * 计算的工厂类 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class CalculatorFactory { private static CalculatorFactory calculatorFactoryInstance = null; private CalculatorFactory(){ } public static CalculatorFactory GetInstance() { if (calculatorFactoryInstance == null) { calculatorFactoryInstance = new CalculatorFactory(); } return calculatorFactoryInstance; } public static Calculator getCalculatorInstance(String type){ Calculator cal = null; if("Addition".equals(type)){ cal = new Addition(); }else if("SubStraction".equals(type)){ cal = new SubStraction(); }else if("Multiplication".equals(type)){ cal = new Multiplication(); }else if("Division".equals(type)){ cal = new Division(); }else{ System.out.println("operater error!"); } return cal; }}
下面这五个类是一个整个,不要一听说五个类就吓了一跳,其实每个类及一句话,非常简单
接口类:
package org.study.father;/** * 算法的父类 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public interface Calculator { public double count(double a,double b);}
实现接口的(加减乘除)四个类:
package org.study.son;import org.study.father.Calculator;/** * 加法 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class Addition implements Calculator { @Override public double count(double a, double b) { // TODO Auto-generated method stub return a + b; }}
package org.study.son;import org.study.father.Calculator;/** * 减法 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class SubStraction implements Calculator { @Override public double count(double a, double b) { return a - b; }}
package org.study.son;import org.study.father.Calculator;/** * 乘法 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class Multiplication implements Calculator { @Override public double count(double a, double b) { // TODO Auto-generated method stub return a * b; }}
package org.study.son;import org.study.father.Calculator;/** * 除法 * @author: lujie * @data: 2014年5月13日 * @email: athenalu@foxmail.com */public class Division implements Calculator { @Override public double count(double a, double b) { // TODO Auto-generated method stub return a / b; }}
所有代码都粘完了,中间还有好多地方有待优化,感觉有点累,就懒得再修改了,放到这里留个纪念。