闲来无聊,一个月前学习一下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(" ");
		Stack<String> stack = new Stack<String>();
		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<Double> stack = new Stack<Double>();
		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<String> endExpressionStr = new ArrayList<String>();
		Stack<String> stack = new Stack<String>();
		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;
	}

}

所有代码都粘完了,中间还有好多地方有待优化,感觉有点累,就懒得再修改了,放到这里留个纪念。