이야기박스

Java) 후위수식 계산기 본문

Programming Language/JAVA

Java) 후위수식 계산기

박스님 2017. 5. 26. 14:48
반응형

후위수식 계산기입니다.

마우스 클릭 혹은 키보드로 입력을 받고, 계산을 하는 방식입니다 ^^

간단하게 정수의 계산만 구현했습니다.


<< 클래스 >>


Main - Frame을 키는 클래스

Calculator - JPanel을 상속받아 전체적인 이벤트 및  화면을 담당하는 클래스

NumPad - 버튼들을 담당하는 클래스

History - 결과물을 출력해주는 클래스

Convert - 후위 수식으로 전환해주는 클래스

Evaluate - 후위 수식을 통해 계산을 해주는 클레스

Stack - 스택 클래스





1. Main class

import javax.swing.*;


public class Main {

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		Calculator primary = new Calculator();
		
		frame.getContentPane().add(primary);
		frame.pack();
		frame.setVisible(true);		
	}
}



2.  Calculator class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Calculator extends JPanel implements KeyListener {	
	private Dimension	displaySize;
	private JPanel 		title;
	private History		history;
	private NumPad		numPad;
	private String		strInfix, strResult;
	private CalcListener listener;
	private JButton[]	btnNums, btnOperators;
	
	public Calculator() {
		displaySize = new Dimension(800,800);
		this.setPreferredSize(displaySize);
		this.setBackground(Color.black);
		this.setLayout(null);
		
		strInfix = new String("");
		strResult = new String("");
		
		listener = new CalcListener();
		addKeyListener(this);
		setFocusable(true);
		
		layOut();		
	} // Calculator()
	
	public void layOut() {
		title = new JPanel();
		title.setBackground(Color.white);
		title.setBounds(0, 0, displaySize.width, displaySize.height/8);
		this.add(title);
		
		history = new History();
		history.setBounds(0,displaySize.height/8,displaySize.width,displaySize.height/8);
		this.add(history);
		
		numPad = new NumPad(this, listener);
		numPad.setBounds(0, displaySize.height*2/8, displaySize.width, displaySize.height*6/8);
		this.add(numPad);
	}	// layOut()

	public void setBtns(JButton[] nums, JButton[] opers) {
		btnNums = nums;
		btnOperators = opers;
	}	// setBtns()
	
	public void keyPressed(KeyEvent e) {
	}	// keyPressed()

	public void keyReleased(KeyEvent e) {
		
	}	// keyReleased()

	public void keyTyped(KeyEvent e) {
		char input = e.getKeyChar();
		// 0~9
		if(input >=  '0' && input <= '9') {
			strInfix = strInfix + input;
			history.setNow(strInfix);
		}
		// +*-/
		else if(input == '+' || input == '-' || input == '*' || input == '/') {
			strInfix = strInfix + input;
			history.setNow(strInfix);
		}
		// clear
		else if(input == 'c') {
			strInfix = "";
			history.setNow("0");
		}
		// calc
		else if (input == '=' || input == '\n') {
			doCalc();
		}		
	}	// keyTyped()
	
	public void doCalc() {
		// convert to postfix
		Convert convert = new Convert(strInfix);
		// calculate
		Evaluate evaluate = new Evaluate(convert.getQue());
		Double result = evaluate.getResult();
		
		// round
		int round	= (int)Math.round(result);
		
		// display
		strResult = Integer.toString(round);
		history.setNow(strResult);
		history.setBefore(strInfix);
		
		// feedback
		strInfix = strResult;				
	}	// doCalc()
	
	
	private class CalcListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			JButton but = (JButton)e.getSource();
			
			// clear
			if(e.getSource() == btnNums[11]) {
				strInfix = "";
				history.setNow("0");
			} 
			// calc
			else if(e.getSource() == btnNums[10]) {
				doCalc();
			} else {
				strInfix = strInfix + but.getText();
				history.setNow(strInfix);
			}
		}	// actionPerformed()
	}	// CalcListener class	
}	// Calculator class



3. NumPad class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class NumPad extends JPanel {
	private JPanel		numbers, operators;
	private JButton[]	btnNums, btnOperators;
	private String[]	strNums={"7","8","9","4","5","6","1","2","3","0","=","C"};
	private String[]	strOperators = {"+","-","*","/"};
	private ActionListener listener;
	private Calculator	calc;
	
	// 800 , 600
	public NumPad(Calculator c, ActionListener l) {
		this.setLayout(null);		

		calc = c;
		listener = l;
		design();
	} // NumPad()
	
	public void design() {
		numbers = new JPanel();
		numbers.setBounds(40, 50, 600, 500);
		numbers.setLayout(new GridLayout(4,3));
		this.add(numbers);
		
		operators = new JPanel();
		operators.setBounds(660, 50, 100, 500);
		operators.setLayout(new GridLayout(4,1));
		this.add(operators);
		
		addButton();
	}	// design()
	
	public void addButton() {
		btnNums = new JButton[12];
		for(int i=0; i<12; i++) {
			btnNums[i] = new JButton(strNums[i]);
			btnNums[i].addActionListener(listener);
			numbers.add(btnNums[i]);
		}
		
		btnOperators = new JButton[4];
		for(int i=0; i<4; i++) {
			btnOperators[i] = new JButton(strOperators[i]);
			btnOperators[i].addActionListener(listener);
			operators.add(btnOperators[i]);
		}
		
		calc.setBtns(btnNums, btnOperators);
	}	// addButton()
	
}	// NumPad class



4.  History class

import javax.swing.*;
import java.awt.*;


public class History extends JPanel{
	private JLabel lblNow, lblBefore;
	
	// 800, 100
	public History() {
		this.setLayout(null);
		
		design();
		
	}	// History()
	
	
	public void design() {		
		lblNow = new JLabel("0");
		lblNow.setBounds(50,60,700,40);
		lblNow.setHorizontalAlignment(SwingConstants.LEFT);
		lblNow.setFont(new Font("Monofour",Font.ITALIC,25));
		this.add(lblNow);
		
		lblBefore = new JLabel();
		lblBefore.setBounds(50,10,700,40);
		lblBefore.setHorizontalAlignment(SwingConstants.LEFT);
		lblBefore.setFont(new Font("Monofour",Font.ITALIC,15));
		this.add(lblBefore);
	}	// design()
	
	public  void setNow(String now) {
		lblNow.setText(now);
	}	// setNow()
	
	public void setBefore(String before) {
		lblBefore.setText(before);
	}
	
}	// History class




5. Stack class

public class Stack {

	private Object[] list;
	private int top;
	private int max;
	
	public Stack() {
		max = 150;
		top = -1;
		list = new Object[max];
	}
	
	public void push(Object elem){
		list[++top] = elem;
	}
	
	public Object pop() {
		top--;		
		return list[top+1];
	}
	
	public Object getStack() {
		return list[top];		
	}
	
	public boolean isEmpty() {
		return top < 0;
	}
	
	public int getTop() {
		return top;
	}
	
}	// Stack class



6. Convert class

import java.util.regex.*;
import java.util.*;

public class Convert {

	private Stack	stack;
	private String	tmp;
	private StringBuilder	postfix;
	private Pattern pat;
	private Matcher mat;
	private Queue postfixQue;
	
	public Convert(String infix) {
		
		postfix = new StringBuilder();
		postfixQue = new LinkedList();
		stack = new Stack();
		
		pat = Pattern.compile("[0-9]+|\\(|\\)|\\+|\\-|\\*|\\/");
		mat = pat.matcher(infix);
		
		while(mat.find()) {
			tmp = mat.group();

			if(isNumber(tmp)) {
				postfix.append(tmp);
				postfixQue.add(tmp);
			}
			else if (tmp.equals("(")) {
				stack.push(tmp);
			}
			else if (tmp.equals(")")) {
				while ( stack.getStack().equals("(") ) {
					String savePop = (String)stack.pop();
					postfix.append(savePop);
					postfixQue.add(savePop);
				}
				stack.pop();
			}	
			else {				
				while(!stack.isEmpty() && checkPriority(tmp)) {
					String savePop = (String)stack.pop();
					postfix.append(savePop);
					postfixQue.add(savePop);
				}				
				stack.push(tmp);				
			}	// if.. else			
		}	// for i
		
		while(!stack.isEmpty()) {
			String savePop = (String)stack.pop();
			postfix.append(savePop);
			postfixQue.add(savePop);
		}
		
	}	// Convert()
	
	public boolean isNumber(String str) {
	    try {
	        Double.parseDouble(str);
	        return true;
	    } catch (NumberFormatException e) {
	        return false;
	    }	// try.. catch
	}	// isStringDouble()
	
	public boolean checkPriority(String tmp) {
		return priority(tmp) <= priority((String)stack.getStack());
	}
	
	public int priority(String word) {
		switch (word) {
		case "*": return 5;
		case "/": return 5;
		case "+": return 4;
		case "-": return 4;
		default: return 0;
		}	// switch
	}	// priority()

	public Queue getQue() {
		return postfixQue;
	}
	
}	// Convert class




7. Evaluate class

import java.util.*;


public class Evaluate {
	private double	result, oper1, oper2;
	private Stack	stack;
	private String	tmp;
	
	public Evaluate(Queue postfix) {
		
		stack = new Stack();
		
		while(!postfix.isEmpty()) {
			tmp = postfix.remove();
			
			if(isNumber(tmp)) {
				stack.push(Double.valueOf(tmp));
			}
			else {
				oper2 = (double)stack.pop();
				oper1 = (double)stack.pop();
				stack.push(doOperator(tmp,oper1,oper2));
			}
		}
		
		result = (double)stack.pop();
		
	}	// Evaluate()
	
	public boolean isNumber(String str) {
	    try {
	        Double.parseDouble(str);
	        return true;
	    } catch (NumberFormatException e) {
	        return false;
	    }	// try.. catch
	}	// isStringDouble()
	
	public double doOperator(String op, double oper1, double oper2) {
		double retVal;

		switch (op) {
		case "+": retVal = oper1 + oper2; break;
		case "-": retVal = oper1 - oper2; break;
		case "*": retVal = oper1 * oper2; break;
		case "/": retVal = oper1 / oper2; break;
		default: retVal = 0; break;
		}

		return retVal;
	}

	public double getResult() {
		return result;
	}
	
}	// Evaluate class




<< 실행 화면 >>





<< 마무리 >> 

디자인은 좀 투박합니다.. ㅎㅎ

어려운 코딩이 아닌만큼 금방 끝났네요.

패턴분석쪽은 잘 몰라서 구글링하다가 찾았어요 ㅎㅎ..

이쪽을 더 공부해 봐야 할거 같아요

그럼 20000

반응형

'Programming Language > JAVA' 카테고리의 다른 글

Effective java 3/E - study 시작  (0) 2018.11.16
Java) join 메서드  (0) 2017.11.24
Java) 하노이 탑, 중간 체크  (0) 2017.03.25
Java) Hanoi top 계획  (0) 2017.03.25
JAVA - 로또 번호 뽑기  (0) 2017.03.17