24.04.30 화 TIL(Today I Learned) +

신민금·2024년 4월 30일
0
post-thumbnail

TIL(Today I Learned)

: 매일 저녁, 하루를 마무리하며 작성 !
: ⭕ 지식 위주, 학습한 것을 노트 정리한다고 생각하고 작성하면서 머리 속 흩어져있는 지식들을 정리 !

Java 개인 프로젝트

계산기 Level 3 요구사항

  1. 현재 사칙연산 계산기는 +, -, *, /, % 이렇게 총 5가지 연산 타입으로 구성되어있습니다.
  • Enum 타입을 활용하여 연산자 타입에 대한 정보를 관리하고 이를 사칙연산 계산기 ArithmeticCalculator 클래스에 활용 해봅니다.
  1. 지금까지는 ArithmeticCalculator, 즉 사칙연산 계산기는 양의 정수(0 포함)를 매개변수로 전달받아 연산을 수행했습니다.
  • 이제부터는 양의 정수 뿐만 아니라 실수, 즉 double 타입의 값을 전달 받았을 경우에도 연산이 수행되도록, 즉 피연산자를 여러 타입으로 받을 수 있도록 기능을 확장하고 싶습니다. (ArithmeticCalculator 클래스의 연산 메서드(calculate))
  • 위 요구사항을 만족할 수 있도록 ArithmeticCalculator 클래스를 수정합니다. (제네릭스) (추가적으로 수정이 필요한 다른 클래스나 메서드가 있다면 같이 수정 해주세요.)
  1. 저장된 연산 결과들 중 Scanner로 입력받은 값보다 큰 결과 값 들을 출력하고 싶습니다.
  • ArithmeticCalculator 클래스에 위 요구사항을 만족하는 조회 메서드를 구현합니다.
  • 단, 해당 메서드를 구현할 때 Lambda & Stream을 활용하여 구현합니다. (Java 강의에서 람다 & 스트림을 학습 및 복습 하시고 적용 해보세요!)
  • 추가) 람다 & 스트림 학습을 위해 여러 가지 조회 조건들을 추가하여 구현 해보시면 학습에 많은 도움이 되실 수 있습니다.

// Calculator class

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;

public abstract class Calculator {
    /* 연산 결과를 저장하는 컬렉션 타입 필드 선언 및 생성 */
    /* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
    private static int total = 0;
    private static List<Double> resultList;

    // 원의 넓이를 구하는 필드와 메서드 선언과 구현 ----------------------------

    /* 원의 넓이 결과를 저장하는 컬렉션 타입 필드 선언 및 생성 */
    /* 원의 넓이 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
    private static double AreaTotal = 0;
    private static List<Double> AreaResultList;
    /* 원주율은 pi 이기에 상수로 생성*/
    private static final double PI = 3.141592;


    public enum Operator {
        PLUS("+", (a, b) -> (a + b)),
        MINUS("-", (a, b) -> (a - b)),
        MULTIPLY("*", (a, b) -> (a * b)),
        DIVIDE("/", (a, b) -> (a / b)),
        MOD("%", (a, b) -> (a / b));

        private final String op;
        private final BiFunction<Double, Double, Double> biFunction;

        Operator(String op, BiFunction<Double, Double, Double> biFunction) {
            this.op = op;
            this.biFunction = biFunction;
        }

        public Double calculate(double a, double b) {
            return this.biFunction.apply(a, b);
        }
    }

    /* Calculator 기본 생성자 구현 */
    public Calculator() {
        resultList = new ArrayList<>(); // 생성자에서 컬렉션 필드 초기화
        AreaResultList = new ArrayList<>();
    }

    /* 사칙연산 저장 리스트 Getter 구현 */
    public List<Double> getResultList() {
        return resultList;
    }

    /* 원의 넓이 저장 필드 Getter, Setter, 조회 메서드 구현 */
    /* 원의 넓이 결과 저장 리스트 Getter 구현 */
    public List<Double> getAreaResultList() {
        return AreaResultList;
    }


    public Double calculate(int Number1, int Number2, char operator) throws CalculatorException {
        throw new UnsupportedOperationException("ArithmeticCalculator 또는 CircleCalculator의 calculate 메서드를 사용하세요.");
    }

    /* 원의 넓이를 구하는 메서드 선언*/
    public double calculateCircleArea(int r) throws CalculatorException {
        throw new UnsupportedOperationException("CircleCalculator의 calculateCircleArea 메서드를 사용하세요.");
    }

    // removeResult 메서드 구현
    public void removeResult() {
        // 첫 번째 결과 삭제 오버라이딩으로 하단에서 구현
        throw new UnsupportedOperationException("ArithmeticCalculator 또는 CircleCalculator의 removeResult 메서드를 사용하세요.");
    }

    // 사칙 연산의 inquiryResults 메서드 오버라이딩
    public abstract void inquirybiggerResults(int num1, int num2);

    // 사칙 연산의 inquiryResults 메서드 오버라이딩

    // inquiryResults 메서드 구현
    public void inquiryResults() {
        // 배열에 저장된 연산 결과를 출력합니다.
        // 오버라이딩으로 하단에서 구현
        throw new UnsupportedOperationException("ArithmeticCalculator 또는 CircleCalculator의 inquiryResults 메서드를 사용하세요.");
    }

    public static class ArithmeticCalculator extends Calculator {

        @Override
        public Double calculate(int Number1, int Number2, char operator) throws CalculatorException {
            Double answer;
            if (Number1 <= 0 && Number2 <= 0) {
                throw new CalculatorException("두 정수가 모두 0 이상이어야 합니다.");
            } else {
                switch (operator) {
                    case '+':
                        answer = Operator.PLUS.calculate(Number1, Number2);
                        break;
                    case '-':
                        answer = Operator.MINUS.calculate(Number1, Number2);
                        break;
                    case '*':
                        answer = Operator.MULTIPLY.calculate(Number1, Number2);
                        break;
                    case '/':
                        if (Number2 == 0) {
                            throw new CalculatorException("나눗셈 연산에서 분모(두번째 정수)에 0이 입력될 수 없습니다.");
                        }
                        answer = Operator.DIVIDE.calculate(Number1, Number2);
                        break;
                    case '%':
                        answer = Operator.MOD.calculate(Number1, Number2);
                        break;
                    default:
                        throw new CalculatorException("올바르지 않은 연산자입니다.");
                }
            }
            getResultList().add(answer);

            return answer;
        }

        // 사칙 연산의 removeResult 메서드 오버라이딩
        @Override
        public void removeResult() {
            if (!resultList.isEmpty()) {
                resultList.remove(0); // 첫 번째 결과 삭제
            }
        }


        @Override
        public void inquirybiggerResults(int num1, int num2) {
            // 배열에 저장된 연산 결과를 출력합니다.
            resultList.stream()
                    .filter(number -> number > num1 && number > num2)
                    .forEach(number -> System.out.print(number + " "));
            System.out.println();

        }

        // 사칙 연산의 inquiryResults 메서드 오버라이딩
        @Override
        public void inquiryResults() {
            // 배열에 저장된 연산 결과를 출력합니다.
            for (Double number : resultList) {
                System.out.print(number + " ");
            }
            System.out.println();
        }

    }

    public static class CircleCalculator extends Calculator {
        public CircleCalculator() {

        }

        @Override
        public double calculateCircleArea(int r) throws CalculatorException {
            if (r <= 0) {
                throw new CalculatorException("반지름은 0보다 커야 합니다.");
            }
            double area = r * r * PI;
            //getAreaResultList().add(area);
            return area;
        }

        @Override
        public void inquirybiggerResults(int num1, int num2) {

        }
        // 원의 넓이 구하기 inquiryResults 메서드 오버라이딩
        @Override
        public void inquiryResults() {
            // 배열에 저장된 연산 결과를 출력합니다.
            for (double number : AreaResultList) {
                System.out.print(number + " ");
            }
            System.out.println();
        }

    }

    // 예외 선언 !
    class CalculatorException extends Exception {
        public CalculatorException(String message) {
            super(message);
        }
    }

}



// Main
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);


        Calculator.ArithmeticCalculator arithmeticCalculator = new Calculator.ArithmeticCalculator();
        Calculator.CircleCalculator circleCalculator= new Calculator.CircleCalculator();

        // 1.  Scanner 를 사용하여 양의 정수

        Double result;
        String order = "";

        // 7. 연산 결과가 10개로 고정되지 않고 무한이 저장될 수 있도록 소스 코드를 수정합니다.


        do {
            try {
                /* 사칙연산을 진행할지 원의 너비를 구할지 선택 구현 */
                System.out.print("원의 넓이 구하기 : 1. 사칙연산하기 : 2 ");
                int choose = Integer.parseInt(sc.nextLine());

                if (choose == 1) {
                    // 원의 넓이
                    /* 원의 넓이를 구하는 경우 반지름을 입력받아 원의 넓이를 구한 후 출력*/
                    System.out.print("반지름 입력: ");
                    int radius = Integer.parseInt(sc.nextLine());
                    double areaResult = circleCalculator.calculateCircleArea(radius);
                    System.out.println("원의 넓이: " + areaResult);
                    /* 원의 넓이 저장 */
                    circleCalculator.getAreaResultList().add(areaResult);
                    /* 원의 넓이 리스트 출력 */
                    circleCalculator.inquiryResults();


                } else if (choose == 2) {

                    System.out.print("첫 번째 숫자를 입력하세요: ");
                    // Scanner를 사용하여 양의 정수를 입력받고 적합한 타입의 변수에 저장합니다.
                    int Number1 = Integer.parseInt(sc.nextLine());
                    System.out.print("두 번째 숫자를 입력하세요: ");
                    // Scanner를 사용하여 양의 정수를 입력받고 적합한 타입의 변수에 저장합니다.
                    int Number2 = Integer.parseInt(sc.nextLine());

                    // 2. Scanner를 사용하여 사칙연산 기호를 전달 받을 수 있습니다.
                    System.out.print("사칙연산 기호를 입력하세요: ");
                    // 사칙연산 기호를 적합한 타입으로 선언한 변수에 저장합니다
                    char operator = sc.nextLine().charAt(0);

                    // 3. 입력받은 양의 정수 2개와 사칙연산 기호를 사용하여 연산을 진행한 후 결과값을 출력합니다.

                    result = arithmeticCalculator.calculate(Number1, Number2, operator);
                    //System.out.println("결과: " + result);

                    // 5. 연산 결과 10개를 저장할 수 있는 배열을 선언 및 생성하고 연산의 결과를 저장합니다.

                    // 6. 연산 결과가 10개를 초과하는 경우 가장 먼저 저장된 결과를 삭제하고 새로운 연산 결과가 저장될 수 있도록 소스 코드를 수정합니다.

                    // 7. 연산 결과가 10개로 고정되지 않고 무한이 저장될 수 있도록 소스 코드를 수정합니다.

                    System.out.println(result);

                    System.out.println("가장 먼저 저장된 연산 결과를 삭제하시겠습니까? (remove 입력 시 삭제)");
                    order = sc.nextLine();

                    if (order.equals("remove")) {
                        arithmeticCalculator.removeResult(); // 첫 번째 결과 삭제
                    }

                    // 8. “inquiry”라는 문자열이 입력되면 저장된 연산 결과 전부를 출력합니다.
                    // - foreach(향상된 for문)을 활용하여 구현 해봅니다.

                    System.out.println("저장된 연산결과를 조회하시겠습니까? (inquiry 입력 시 조회)");
                    order = sc.nextLine();
                    if (order.equals("inquiry")) {
                        arithmeticCalculator.inquiryResults();
                    }

                    System.out.println("입력 값보다 큰 연산결과를 조회하시겠습니까? (biggerinquiry 입력 시 조회)");
                    order = sc.nextLine();
                    if (order.equals("biggerinquiry")) {
                        arithmeticCalculator.inquirybiggerResults(Number1, Number2);
                    }
                }
            } catch (NumberFormatException e) {
                System.out.println("올바른 숫자를 입력하세요.");
            } catch (Calculator.CalculatorException e) {
                System.out.println("오류: " + e.getMessage());
            }

            System.out.print("더 계산하시겠습니까? (exit 입력 시 종료) ");
            order = sc.nextLine();

            // 4. 반복문을 사용하여 반복의 종료를 알려주는 “exit” 문자열을 입력하기 전까지
            // 무한으로 계산을 진행할 수 있도록 소스 코드를 수정합니다.

        } while (!order.equals("exit"));


        sc.close();
    }
}






알고리즘 코드카타

  • 문제 설명
    정수 n이 주어질 때, n이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.
  • 제한사항
    0 < n ≤ 1000
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    int answer = 0;
    for(int i=0; i<=n; i++ ){
        if(i % 2 == 0){
            answer = answer + i;
        }
    }
    
    return answer;
}

Java 심화반 1회차 : Java를 능숙히 사용할 수 있고, 조금 더 단단한 Java를 다지는 반 OT


Git 심화 특강

profile
야옹

0개의 댓글