우아한 프로그래밍
article thumbnail

 

1. 1. 소스코드

<java />
import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javax.swing.*; import java.text.DecimalFormat; import java.util.*; public class MyApp extends Application { // 연산스택 Stack<String> stack = new Stack<>(); // 결과 List<String> result = new ArrayList<>(); // 출력 List<String> output = new ArrayList<>(); // 계산 화면 TextArea txtA; @Override public void start(Stage primaryStage) throws Exception { primaryStage.setTitle("19m3283"); primaryStage.setWidth(270); primaryStage.setHeight(410); MenuBar mBar = new MenuBar(); Menu mFile = new Menu("ファイル"); MenuItem miOpen = new MenuItem("開く"); MenuItem miExit = new MenuItem("終了"); mFile.getItems().add(miOpen); mFile.getItems().add(miExit); mBar.getMenus().add(mFile); BorderPane root = new BorderPane(); root.setTop(mBar); VBox vbox = new VBox(); txtA = new TextArea(""); txtA.setPrefHeight(100); VBox.setMargin(txtA, new Insets(3,3, 0, 3)); HBox hbox = new HBox(); Button bt = new Button("sin"); bt.setPrefSize(60, 35); HBox.setMargin(bt, new Insets(3,3, 3, 3)); Button bt1 = new Button("cos"); bt1.setPrefSize(60, 35); HBox.setMargin(bt1, new Insets(3, 0, 3, 0)); Button bt2 = new Button("tan"); bt2.setPrefSize(60, 35); HBox.setMargin(bt2, new Insets(3, 3, 3, 3)); Button bt3 = new Button("削除"); bt3.setPrefSize(60, 35); HBox.setMargin(bt3, new Insets(3, 3, 3, 0)); root.setBottom(hbox); hbox.getChildren().addAll(bt,bt1,bt2,bt3); HBox hbox1 = new HBox(); Button bt4 = new Button("指数"); bt4.setPrefSize(60, 35); HBox.setMargin(bt4, new Insets(0, 3,3, 3)); Button bt5 = new Button("log"); bt5.setPrefSize(60, 35); HBox.setMargin(bt5, new Insets(0, 0, 3, 0)); Button bt6 = new Button("剰余"); bt6.setPrefSize(60, 35); HBox.setMargin(bt6, new Insets(0, 3, 3, 3)); Button bt7 = new Button("√"); bt7.setPrefSize(60, 35); HBox.setMargin(bt7, new Insets(0, 3, 3, 0)); root.setBottom(hbox1); hbox1.getChildren().addAll(bt4,bt5,bt6,bt7); HBox hbox2 = new HBox(); Button bt8 = new Button("1/X"); bt8.setPrefSize(60, 35); HBox.setMargin(bt8, new Insets(0, 3,3, 3)); Button bt9 = new Button("CE"); bt9.setPrefSize(60, 35); HBox.setMargin(bt9, new Insets(0, 0,3, 0)); Button bt10 = new Button("C"); bt10.setPrefSize(60, 35); HBox.setMargin(bt10, new Insets(0, 0,3, 3)); Button bt11 = new Button("/"); bt11.setPrefSize(60, 35); HBox.setMargin(bt11, new Insets(0, 3,3, 3)); root.setBottom(hbox2); hbox2.getChildren().addAll(bt8,bt9,bt10,bt11); HBox hbox3 = new HBox(); Button bt12 = new Button("1"); bt12.setPrefSize(60, 35); bt12.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt12, new Insets(0, 3,3, 3)); Button bt13 = new Button("2"); bt13.setPrefSize(60, 35); bt13.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt13, new Insets(0, 3,3, 0)); Button bt14 = new Button("3"); bt14.setPrefSize(60, 35); bt14.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt14, new Insets(0, 3,3, 0)); Button bt15 = new Button("x"); bt15.setPrefSize(60, 35); HBox.setMargin(bt15, new Insets(0, 3,3, 0)); root.setBottom(hbox3); hbox3.getChildren().addAll(bt12,bt13,bt14,bt15); HBox hbox4 = new HBox(); Button bt16 = new Button("4"); bt16.setPrefSize(60, 35); bt16.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt16, new Insets(0, 3,3, 3)); Button bt17 = new Button("5"); bt17.setPrefSize(60, 35); bt17.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt17, new Insets(0, 0,3, 0)); Button bt18 = new Button("6"); bt18.setPrefSize(60, 35); bt18.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt18, new Insets(0, 0,3, 3)); Button bt19 = new Button("ㅡ"); bt19.setPrefSize(60, 35); HBox.setMargin(bt19, new Insets(0, 0,3, 3)); root.setBottom(hbox4); hbox4.getChildren().addAll(bt16,bt17,bt18,bt19); HBox hbox5 = new HBox(); Button bt20 = new Button("7"); bt20.setPrefSize(60, 35); bt20.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt20, new Insets(0, 3,3, 3)); Button bt21 = new Button("8"); bt21.setPrefSize(60, 35); bt21.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt21, new Insets(0, 3,3, 0)); Button bt22 = new Button("9"); bt22.setPrefSize(60, 35); bt22.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt22, new Insets(0, 3,3, 0)); Button bt23 = new Button("+"); bt23.setPrefSize(60, 35); HBox.setMargin(bt23, new Insets(0, 3,3, 0)); root.setBottom(hbox5); hbox5.getChildren().addAll(bt20,bt21,bt22,bt23); HBox hbox6 = new HBox(); Button bt24 = new Button("+/ㅡ"); bt24.setPrefSize(60, 35); bt24.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt24, new Insets(0, 0,3, 3)); Button bt25 = new Button("0"); bt25.setPrefSize(60, 35); bt25.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt25, new Insets(0, 0,3, 3)); Button bt26 = new Button("."); bt26.setPrefSize(60, 35); bt26.setStyle("-fx-border-color: GRAY;-fx-border-width: 1px;-fx-background-color : WHITE"); HBox.setMargin(bt26, new Insets(0, 0,3, 3)); Button bt27 = new Button("="); bt27.setPrefSize(60, 35); HBox.setMargin(bt27, new Insets(0, 0,3, 3)); root.setBottom(hbox6); hbox6.getChildren().addAll(bt24,bt25,bt26,bt27); root.setCenter(vbox); vbox.getChildren().addAll(txtA,hbox,hbox1,hbox2,hbox3,hbox4,hbox5,hbox6); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); //Stack 내에 있을 때 연산자 우선순위 : 낮->높 HashMap<String, Integer> inP = new HashMap<String, Integer>(); inP.put("(", 0); // 왼쪽 괄호는 스택 내에 있을 땐 우선순위 제일 낮음 inP.put("+", 1); // 따라서 어떤 연산자든 위에 쌓일 수 있음 inP.put("-", 1); inP.put("*", 2); inP.put("/", 2); //Stack 밖에서의 연산자 우선순위 : 낮->높 HashMap<String, Integer> outP = new HashMap<String, Integer>(); outP.put("+", 1); outP.put("-", 1); outP.put("*", 2); outP.put("/", 2); outP.put("(", 3); // [C] bt10.setOnAction(event -> { txtA.setText(""); }); // [CE] bt9.setOnAction(event -> { String v = txtA.getText(); if( v .length() != 0){ txtA.setText(v.substring(0, v.length() - 1)); } }); // [/] bt11.setOnAction(event -> { txtA.setText(txtA.getText() + "/"); }); // [1] bt12.setOnAction(event -> { txtA.setText(txtA.getText() + "1"); }); // [2] bt13.setOnAction(event -> { txtA.setText(txtA.getText() + "2"); }); // [3] bt14.setOnAction(event -> { txtA.setText(txtA.getText() + "3"); }); // [*] bt15.setOnAction(event -> { txtA.setText(txtA.getText() + "*"); }); // [4] bt16.setOnAction(event -> { txtA.setText(txtA.getText() + "4"); }); // [5] bt17.setOnAction(event -> { txtA.setText(txtA.getText() + "5"); }); // [6] bt18.setOnAction(event -> { txtA.setText(txtA.getText() + "6"); }); // [-] bt19.setOnAction(event -> { txtA.setText(txtA.getText() + "-"); }); // [7] bt20.setOnAction(event -> { txtA.setText(txtA.getText() + "7"); }); // [8] bt21.setOnAction(event -> { txtA.setText(txtA.getText() + "8"); }); // [9] bt22.setOnAction(event -> { txtA.setText(txtA.getText() + "9"); }); // [+] bt23.setOnAction(event -> { txtA.setText(txtA.getText() + "+"); }); // [0] bt25.setOnAction(event -> { txtA.setText(txtA.getText() + "0"); }); // [.] bt26.setOnAction(event -> { txtA.setText(txtA.getText() + "."); }); // [sin] bt.setOnAction(event -> { txtA.setText(txtA.getText() + "sin"); }); // [tan] bt2.setOnAction(event -> { txtA.setText(txtA.getText() + "tan"); }); // [cos] bt1.setOnAction(event -> { txtA.setText(txtA.getText() + "cos"); }); // [削除] 삭제 bt3.setOnAction(event -> { String v = txtA.getText(); if( v .length() != 0){ txtA.setText(v.substring(0, v.length() - 1)); } }); // [指数] 지수 bt4.setOnAction(event -> { txtA.setText(txtA.getText() + "e^"); }); // [剰余] 거듭제곱 bt6.setOnAction(event -> { txtA.setText(txtA.getText() + "^"); }); // [√] 루트 bt7.setOnAction(event -> { txtA.setText(txtA.getText() + "√"); }); // [1/X] 역수 bt8.setOnAction(event -> { String v = txtA.getText(); txtA.setText("1/("+ v +")"); }); // [+/-] 루트 bt24.setOnAction(event -> { String v = txtA.getText(); txtA.setText("-1*("+ v +")"); }); // [=] bt27.setOnAction(event -> { try { result.clear(); output.clear(); StringBuffer buffer = new StringBuffer(); String expression = txtA.getText(); for( int i = 0; i < expression.length() ; i++) { String c = String.valueOf(expression.charAt(i)); if ("+".equals(c) || "-".equals(c) || "*".equals(c) || "/".equals(c)) { String v = Calculate(buffer.toString()); result.add(v); result.add(c); buffer.setLength(0); } else if ("(".equals(c) || ")".equals(c)){ result.add(c); }else{ buffer.append(c); } } if( buffer.length() != 0 ) { String v = Calculate(buffer.toString()); result.add(v); buffer.setLength(0); } StringTokenizer st = new StringTokenizer(String.join(" ", result)); while(st.hasMoreTokens()) { String token = st.nextToken(); if(token.equals("(") || token.equals("/") || token.equals("*") || token.equals("-") || token.equals("+")) { //스택이 비어있으면 if(stack.isEmpty()) { stack.push(token); //스택 비어있지 않으면 }else { // 우선순위 : top < token if(inP.get(stack.peek()) < outP.get(token)) { stack.push(token); }else { // 우선순위 : top > token while(true) { if(inP.get(stack.peek()) <= outP.get(token)) { stack.push(token); break; } // 우선순위 : top < token 될때까지 Stack pop output.add(stack.pop()); } } } // 토큰이 오른쪽 괄호 } else if(token.equals(")")) { while(true) { if(stack.peek().equals("(")) { stack.pop(); break; } output.add(stack.pop()); } // 토큰이 숫자 } else { output.add(token); } } if(!st.hasMoreTokens()) { while(true) { if(stack.isEmpty()) { break; } output.add(stack.pop()); } } int len = output.size(); Stack<Double> sum = new Stack<Double>(); int i=0; while(i<len) { if(output.get(i).equals("+")) { double p; double q; q = sum.pop(); p = sum.pop(); sum.add(p+q); }else if(output.get(i).equals("-")) { double p; double q; if( sum.size() == 1){ q = sum.pop(); sum.add(-1*q); }else{ q = sum.pop(); p = sum.pop(); sum.add(p-q); } }else if(output.get(i).equals("*")) { double p; double q; q = sum.pop(); p = sum.pop(); sum.add(p*q); }else if(output.get(i).equals("/")) { double p; double q; q = sum.pop(); p = sum.pop(); sum.add(p/q); }else { sum.add(Double.parseDouble(output.get(i))); } i++; } Double s = sum.pop(); DecimalFormat df=new DecimalFormat("#.###############"); txtA.setText(df.format(s)); } catch (Exception e) { JOptionPane.showMessageDialog(null, "수식이 올바른지 확인해주세요."); e.printStackTrace(); } }); } private String Calculate(String v) { if( v.contains("sin")){ String n = v.substring(0, v.indexOf("sin")); String m = v.substring(v.indexOf("sin") + 3, v.length()); if( n.length() == 0){ v = String.valueOf(Math.sin(Double.parseDouble(m))); }else{ v = String.valueOf(Math.sin(Double.parseDouble(m)) * Double.parseDouble(n)); } }else if( v.contains("cos")){ String n = v.substring(0, v.indexOf("cos")); String m = v.substring(v.indexOf("cos") + 3, v.length()); if( n.length() == 0){ v = String.valueOf(Math.cos(Double.parseDouble(m))); }else{ v = String.valueOf(Math.cos(Double.parseDouble(m)) * Double.parseDouble(n)); } }else if( v.contains("tan")){ String n = v.substring(0, v.indexOf("tan")); String m = v.substring(v.indexOf("tan") + 3, v.length()); if( n.length() == 0){ v = String.valueOf(Math.tan(Double.parseDouble(m))); }else{ v = String.valueOf(Math.tan(Double.parseDouble(m)) * Double.parseDouble(n)); } }else if( v.contains("e^")){ String n = v.substring(0, v.indexOf("e^")); String m = v.substring(v.indexOf("e^") + 2, v.length()); if( n.length() == 0){ v = String.valueOf(Math.exp(Double.parseDouble(m))); }else{ v = String.valueOf(Math.pow( 2.71828 * Double.parseDouble(n), Double.parseDouble(m))); } }else if( v.contains("^")){ String n = v.substring(0, v.indexOf("^")); String m = v.substring(v.indexOf("^") + 1, v.length()); v = String.valueOf(Math.pow(Double.parseDouble(n), Double.parseDouble(m))); }else if( v.contains("√")){ String n = v.substring(0, v.indexOf("√")); String m = v.substring(v.indexOf("√") + 1, v.length()); if( n.length() == 0){ v = String.valueOf(Math.sqrt(Double.parseDouble(m))); }else{ v = String.valueOf(Math.sqrt(Double.parseDouble(m)) * Double.parseDouble(n)); } } return v; } public static void main(String[] args) { launch(args); } }

2. 2. 결과

공학용계산기

 

profile

우아한 프로그래밍

@자바조아!

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!