ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [과제] 계산기 Lv2
    내일배움캠프/과제 2025. 3. 6. 11:01

    ✅ Lv2. 클래스를 적용해 기본적인 연산을 수행할 수 있는 계산기 만들기

     

    1️⃣ 과제 조건

    • 사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
      • 사칙연산을 수행한 후, 결과값을 반환하는 메서드 구현
      • 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성
      • 1) 양의 정수 2개(0 포함)와 연산 기호를 매개변수로 받아 사칙연산(➕,➖,✖️,➗) 기능을 수행한 후 2) 결과 값을 반환하는 메서드와 연산 결과를 저장하는 컬렉션 타입 필드를 가진 Calculator 클래스를 생성.
      • 예시코드
        public class Calculator {
            /* 연산 결과를 저장하는 컬렉션 타입 필드 선언 및 생성 */
        
            public 반환타입 calculate(...매개변수) {
                /* 위 요구사항에 맞게 구현 */
                /* return 연산 결과 */
            }
        }


    • Lv 1에서 구현한 App 클래스의 main 메서드에 Calculator 클래스가 활용될 수 있도록 수정
      • 연산 수행 역할은 Calculator 클래스가 담당
        • 연산 결과는 Calculator 클래스의 연산 결과를 저장하는 필드에 저장
      • 소스 코드 수정 후에도 수정 전의 기능들이 반드시 똑같이 동작해야함.
      • 예시코드
        public class App {
            public static void main(String[] args) {
                /* Calculator 인스턴스 생성 */
        
                Scanner sc = new Scanner(System.in);
        
                /* 반복문 시작 */
                    System.out.print("첫 번째 숫자를 입력하세요:");
                    int num1 = sc.nextInt();
                    System.out.print("두 번째 숫자를 입력하세요:");
                    int num2 = sc.nextInt();
        
                    System.out.print("사칙연산 기호를 입력하세요: ");
                    char operator = sc.next().charAt(0);
        
                    /* 위 요구사항에 맞게 소스 코드 수정 */
        
                    System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
                    ...
                /* 반복문 종료 */
            }
        }

    • App 클래스의 main 메서드에서 Calculator 클래스의 연산 결과를 저장하고 있는 컬렉션 필드에 직접 접근하지 못하도록 수정 (캡슐화)
      • 간접 접근을 통해 필드에 접근하여 가져올 수 있도록 구현. (Getter 메서드)
      •  간접 접근을 통해 필드에 접근하여 수정할 수 있도록 구현. (Setter 메서드)
      •  위 요구사항을 모두 구현 했다면 App 클래스의 main 메서드에서 위에서 구현한 메서드를 활용.
      • 예시코드
        public class Calculator {
        		/* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
        		
            public 반환타입 calculate(...매개변수) {
                ...
            }
            
            /* Getter 메서드 구현 */
            /* Setter 메서드 구현 */
        }
        
        public class App {
            public static void main(String[] args) {
                /* Calculator 인스턴스 생성 */
        
                Scanner sc = new Scanner(System.in);
        
                /* 반복문 시작 */
                    System.out.print("첫 번째 숫자를 입력하세요:");
                    int num1 = sc.nextInt();
                    System.out.print("두 번째 숫자를 입력하세요:");
                    int num2 = sc.nextInt();
        
                    System.out.print("사칙연산 기호를 입력하세요: ");
                    char operator = sc.next().charAt(0);
        
                    /* 위 요구사항에 맞게 소스 코드 수정 */
        
                    System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
                    ...
                /* 반복문 종료 */
            }
        }
    • Calculator 클래스에 저장된 연산 결과들 중 가장 먼저 저장된 데이터를 삭제하는 기능을 가진 메서드를 구현한 후 App 클래스의 main 메서드에 삭제 메서드가 활용될 수 있도록 수정
      • 키워드 : 컬렉션
        • 컬렉션에서 ‘값을 넣고 제거하는 방법을 이해한다.’가 중요
      • 예시코드
        public class Calculator {
        		/* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
        		
            public 반환타입 calculate(...매개변수) {
                ...
            }
            
            ...
            
            public void removeResult() {
                /* 구현 */
            }
        }
        
        public class App {
            public static void main(String[] args) {
                /* Calculator 인스턴스 생성 */
        
                Scanner sc = new Scanner(System.in);
        
                /* 반복문 시작 */
                    System.out.print("첫 번째 숫자를 입력하세요:");
                    int num1 = sc.nextInt();
                    System.out.print("두 번째 숫자를 입력하세요:");
                    int num2 = sc.nextInt();
        
                    System.out.print("사칙연산 기호를 입력하세요: ");
                    char operator = sc.next().charAt(0);
        
                    /* 위 요구사항에 맞게 소스 코드 수정 */
        
                    System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
                    ...
                /* 반복문 종료 */
            }
        }

    2️⃣ 구현

    while (true) {
    	...
    }
    
    private static String readInput(BufferedReader br) throws IOException {
        String input = br.readLine().trim();
        if (input.equalsIgnoreCase(EXIT_COMMAND)) {
            System.out.println("계산기가 종료되었습니다.");
            System.exit(0);
        }
        return input;
    }
    
    // 양의 정수를 입력받는 메서드 (exit 입력 가능)
    private static int getPositiveInteger(BufferedReader br, String prompt) throws IOException {
        int number = -1;
        while (number < 0) {
            System.out.print(prompt);
            String input = readInput(br);
            try {
                number = Integer.parseInt(input);
                if (number < 0) {
                    System.out.println("\n! 양의 정수를 입력해주세요 !\n");
                }
            } catch (NumberFormatException e) {
                System.out.println("\n! 양의 정수를 입력해주세요 !\n");
            }
        }
        return number;
    }
    
    // 올바른 사칙연산 기호를 입력받는 메서드 (exit 입력 가능)
    private static String getValidOperator(BufferedReader br) throws IOException {
        String operator = "";
        while (!OPERATOR_LIST.contains(operator)) {
            System.out.print("사칙연산 기호를 입력하세요(+, -, *, /) : ");
            operator = readInput(br);
        }
        return operator;
    }
    
    // Y/N 입력을 받는 메서드 (exit 입력 가능)
    private static String getYesNoInput(BufferedReader br, String prompt) throws IOException {
        String input = "";
        while (!YN_LIST.contains(input)) {
            System.out.print(prompt);
            input = readInput(br);
        }
        return input;
    }

     

     

    getPositiveInteger(), getValidOperator(), getYesNoInput() 메서드를 생성하여 입력값을 받음.

    공통으로 readInput() 함수를 생성하여 exit 가 입력되면 시스템이 종료되도록 변경

     

    try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
    	...
    } catch (IOException e) {
    	e.printStackTrace();
    }

     

     

    코드를 try-catch 를 활용하여 br을 선언해줌으로 br.close()를 사용하지 않아도 종료됨

     

    public class Result {
        private int num1;
        private int num2;
        private String operator;
        private int result;
    }

     

    연산 결과를 저장할 Result 객체를 만들어 놓고

     

    public class Calculator {
        private int result;
        private List<Result> resultList = new ArrayList<>();
        
        public void calculate(int num1, int num2, String operator) {
            // 사칙연산 기호에 따라 분기
            this.result = switch (operator) {
                case "+" -> num1 + num2;
                case "-" -> num1 - num2;
                case "*" -> num1 * num2;
                case "/" -> num1 / num2;
                default -> throw new IllegalArgumentException(); // 올바르지 않은 값 입력 시
            };
    
            this.addResult(new Result(num1, num2, operator, this.result));
        }
    }

     

    사칙연산을 수행 후, 결과값 반환 메서드 구현 & 연산 결과를 저장하는 Calculator 클래스를 생성하여 기존 연산에 관련된 기능을 calculate 함수로 생성.

     

    calcuate 에서는 연산 후 result 객체를 생성하여 list에 저장

     

    if (resultYn.equalsIgnoreCase("Y")) {
        int i = 1;
        for (Result res : calculator.getResultList()) {
            System.out.println(i++ + ". " + res.toString());
        }
    }

     

    App 에는 기존 저장된 resulstList 의 결과를 볼 수 있는 기능을 구현

     

    public class Calculator {
        public void removeResult(int index) {
            if (!resultList.isEmpty()) {
                resultList.remove(index - 1);
            }
        }
    }
    if (removeYn.equalsIgnoreCase("Y")) {
        while (true) {
            System.out.print("삭제할 결과 번호를 입력하세요 : ");
            int index = Integer.parseInt(readInput(br));
            int resultSize = calculator.getResultList().size();
    
            if (index <= 0 || index > resultSize) {
                System.out.println("\n! 올바른 결과 번호를 입력해주세요 !\n");
                continue;
            }
            calculator.removeResult(index);
            System.out.println("결과 값 삭제가 완료되었습니다.");
            break;
        }
    }

     

    기존 결과 목록을 보고 삭제할 것인지 물어보아 해당 번호에 맞는 index 를 입력받아 삭제 시키도록 구현.

     

    3️⃣ 정리

    1. App 클래스 (메인 클래스)

    App 클래스는 사용자로부터 입력을 받고, Calculator 클래스의 메서드를 호출하여 연산을 수행하는 역할.

    • 입력 검증 및 반복 처리
      • BufferedReader를 사용하여 입력을 받고, exit 명령어 혹은 Y/N 입력을 통해 계속 계산할지 여부를 확인.
      • getPositiveInteger(), getValidOperator(), getYesNoInput() 메서드를 통해 입력값을 검증.
    • Calculator 클래스 활용
      • 사용자 입력이 올바르게 이루어지면, Calculator의 calculate() 메서드를 호출해 연산을 수행하고, 계산 결과를 컬렉션에 저장.
      • 저장된 결과를 보고 싶을 때는 getResultList()로 가져와 출력하고, 삭제를 원할 경우 removeResult() 메서드를 호출하여 삭제할 수 있음.

     

    2. Calculator 클래스

    Calculator 클래스는 실제 연산을 수행하고 결과를 관리하는 역할.
    여기서는 캡슐화를 적용해 연산 결과가 저장되는 리스트(resultList)에 외부에서 직접 접근하지 못하도록 했고, 필요 시 getter와 setter를 통해 간접적으로 접근할 수 있도록 구현.

    • calculate()
      • 매개변수로 받은 두 정수와 사칙연산 기호에 따라 연산을 수행.
      • switch 구문을 사용하여 각각의 연산을 처리하고, 계산 결과를 this.result에 저장.
      • 계산된 결과를 새로운 Result 객체로 만들어 resultList에 추가.
    • getResult() / setResult()
      • 계산 결과를 읽거나 수정할 수 있도록 제공하는 getter와 setter.
    • getResultList()
      • 저장된 결과 리스트를 반환하는 getter.
    • removeResult()
      • 인덱스로 전달된 계산 결과를 리스트에서 삭제하는 메서드. (리스트 인덱스는 1부터 시작하는 사용자 입력을 보정하여 삭제)

     

    3. Result 클래스

    Result 클래스는 각 계산의 결과를 객체 형태로 저장하기 위해 사용.
    여기서는 두 정수, 연산 기호, 그리고 계산 결과를 필드로 보관하고, toString() 메서드를 오버라이드하여 "num1 연산자 num2 = 결과" 형태의 문자열로 출력할 수 있도록 구현.

     

     

    4️⃣ 최종 코드

    App

    import java.io.*;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class App {
    
        // 상수로 문자열 관리
        private static final String EXIT_COMMAND = "exit";
        private static final List<String> OPERATOR_LIST = new ArrayList<>(Arrays.asList("+", "-", "*", "/"));
        private static final List<String> YN_LIST = new ArrayList<>(Arrays.asList("Y", "N", "y", "n"));
    
        public static void main(String[] args) {
            Calculator calculator = new Calculator();
    
            try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
                System.out.println("계산기를 시작합니다.");
                System.out.println("계산기는 exit 입력 시 종료됩니다.");
    
    
                while (true) {
                    try {
                        int num1 = getPositiveInteger(br, "첫번째 양의 정수를 입력해주세요 : ");
                        int num2 = getPositiveInteger(br, "두번째 양의 정수를 입력해주세요 : ");
                        String operator = getValidOperator(br);
    
                        // calculator 의 calculate 사용
                        calculator.calculate(num1, num2, operator);
                        int result = calculator.getResult();
                        System.out.printf("%d %s %d = %d \n", num1, operator, num2, result);
    
                        String resultYn = getYesNoInput(br, "기존 저장된 결과 값들을 보시겠습니까? (Y/N) : ");
                        if (resultYn.equalsIgnoreCase("Y")) {
                            int i = 1;
                            for (Result res : calculator.getResultList()) {
                                System.out.println(i++ + ". " + res.toString());
                            }
                        }
    
                        String removeYn = getYesNoInput(br, "기존 저장된 결과 값을 삭제하시겠습니까? (Y/N) : ");
                        if (removeYn.equalsIgnoreCase("Y")) {
                            while (true) {
                                System.out.print("삭제할 결과 번호를 입력하세요 : ");
                                int index = Integer.parseInt(readInput(br));
                                int resultSize = calculator.getResultList().size();
    
                                if (index <= 0 || index > resultSize) {
                                    System.out.println("\n! 올바른 결과 번호를 입력해주세요 !\n");
                                    continue;
                                }
                                calculator.removeResult(index);
                                System.out.println("결과 값 삭제가 완료되었습니다.");
                                break;
                            }
                        }
    
                        String continueYn = getYesNoInput(br, "계속 계산하시겠습니까? (Y/N) : ");
                        if (continueYn.equalsIgnoreCase("N")) {
                            break;
                        }
    
                        System.out.println(); // 개행 처리
                    } catch (NumberFormatException e) {
                        System.out.println("\n! 정수를 입력해주세요 !\n");
                    } catch (IllegalArgumentException e) {
                        System.out.println("\n! 올바른 사칙연산 기호를 입력해주세요 !\n");
                    } catch (ArithmeticException e) {
                        System.out.println("\n! 나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다 !\n");
                    }
                }
                System.out.println("계산기가 종료되었습니다.");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        // 입력을 읽고, exit 입력 시 프로그램 종료
        private static String readInput(BufferedReader br) throws IOException {
            String input = br.readLine().trim();
            if (input.equalsIgnoreCase(EXIT_COMMAND)) {
                System.out.println("계산기가 종료되었습니다.");
                System.exit(0);
            }
            return input;
        }
    
        // 양의 정수를 입력받는 메서드 (exit 입력 가능)
        private static int getPositiveInteger(BufferedReader br, String prompt) throws IOException {
            int number = -1;
            while (number < 0) {
                System.out.print(prompt);
                String input = readInput(br);
                try {
                    number = Integer.parseInt(input);
                    if (number < 0) {
                        System.out.println("\n! 양의 정수를 입력해주세요 !\n");
                    }
                } catch (NumberFormatException e) {
                    System.out.println("\n! 양의 정수를 입력해주세요 !\n");
                }
            }
            return number;
        }
    
        // 올바른 사칙연산 기호를 입력받는 메서드 (exit 입력 가능)
        private static String getValidOperator(BufferedReader br) throws IOException {
            String operator = "";
            while (!OPERATOR_LIST.contains(operator)) {
                System.out.print("사칙연산 기호를 입력하세요(+, -, *, /) : ");
                operator = readInput(br);
            }
            return operator;
        }
    
        // Y/N 입력을 받는 메서드 (exit 입력 가능)
        private static String getYesNoInput(BufferedReader br, String prompt) throws IOException {
            String input = "";
            while (!YN_LIST.contains(input)) {
                System.out.print(prompt);
                input = readInput(br);
            }
            return input;
        }
    }

     

     

    Calculator

    import java.util.ArrayList;
    import java.util.List;
    
    public class Calculator {
    
        private int result;
    
        private List<Result> resultList = new ArrayList<>();
    
        public void calculate(int num1, int num2, String operator) {
            // 사칙연산 기호에 따라 분기
            this.result = switch (operator) {
                case "+" -> num1 + num2;
                case "-" -> num1 - num2;
                case "*" -> num1 * num2;
                case "/" -> num1 / num2;
                default -> throw new IllegalArgumentException(); // 올바르지 않은 값 입력 시
            };
    
            this.addResult(new Result(num1, num2, operator, this.result));
        }
    
        public int getResult() {
            return result;
        }
    
        public void setResult(int result) {
            this.result = result;
        }
    
        public List<Result> getResultList() {
            return resultList;
        }
    
        public void addResult(Result result) {
            resultList.add(result);
        }
    
        public void removeResult(int index) {
            if (!resultList.isEmpty()) {
                resultList.remove(index - 1);
            }
        }
    }

     

    Result

    public class Result {
        private int num1;
        private int num2;
        private String operator;
        private int result;
    
        public Result(int num1, int num2, String operator, int result) {
            this.num1 = num1;
            this.num2 = num2;
            this.operator = operator;
            this.result = result;
        }
    
        @Override
        public String toString() {
            return num1 + " " + operator + " " + num2 + " = " + result;
        }
    }

    '내일배움캠프 > 과제' 카테고리의 다른 글

    [과제] 키오스크 필수 Lv3  (0) 2025.03.13
    [과제] 키오스크 필수 Lv2  (1) 2025.03.13
    [과제] 키오스크 필수 Lv1  (0) 2025.03.13
    [과제] 계산기 Lv3  (1) 2025.03.06
    [과제] 계산기 Lv1  (1) 2025.03.05
Designed by Tistory.