상세 컨텐츠

본문 제목

[TIL#13] Study] 코딩 테스트 1

개인 공부/코딩 테스트

by DK9 2023. 11. 1. 01:15

본문

자바 주차가 끝나고 본격적으로 스프링 주차로 넘어가는 시점에서 고민이 많았다. 자바도 안되는데 스프링을 보면 스프링을 알까? 하는 생각에 지금까지 배웠던 것을 정리하고 넘어가고 싶었다. 그러던 찰나에 새로 만난 팀원 중 한 분의 도움을 받을 수 있는 기회가 찾아왔다. 기회를 살려 오늘 배운 것을 정리해보고자 한다.

 

간단한 퀴즈를 도움을 받지 않고 혼자 풀어보는 시간을 가졌다. 또한 잘 모르는 것들은 과감히 배제하고 알고 있는 것들만 사용하여 코드를 구성했다. 어중간한 앎은 독이다.

 

1. 우승 상금 게임

public static void main(String[] args) {
    System.out.println("우승 상금 게임!!!!");

    Scanner sc = new Scanner(System.in); // 숫자 받기

    System.out.print("첫번째 숫자 : "); // 첫번째 숫자
    int firstNumber = sc.nextInt();

    System.out.print("\n두번째 숫자 : "); // 두번째 숫자
    int secondNumber = sc.nextInt();

    int price;                                         // 상금 로직
    int max = Math.max(firstNumber, secondNumber);

    if (firstNumber == secondNumber) {
        price = (firstNumber+secondNumber)*1000;
    } else {
        price = max*1000;
    }

    System.out.println("우승 상금 : " + price);         // 상금 출력
    System.out.println("-------------------------------");
}

첫번째 숫자와 두번째 숫자를 비교해서 두 숫자가 같으면 숫자의 합*1000을 상금으로 받고, 두 숫자가 다르면 보다 큰 숫자*1000을 상금으로 받는다.

  • 1번에서 확실히 배운 것은 System.out.print 와 println의 차이이다. 줄을 바꾸고 안바꾸고의 차이라는 것은 알고 있었지만 사용해보는 것은 확실히 다른 느낌이었다.
  • 초기의 if문에서는 세 가지의 경우의 수를 모두 표시했었다. 코드의 중복이 보여 해결하고 싶어 팀원분께 질문을 드렸고 Math메서드를 사용하여 해결하는 방법을 알게되었다. 꼭 코드를 짜서 해결하는 것만이 능사가 아니라는 것을 새삼 알게되었다.

2. 배수 체크

public static void main(String[] args) {
    System.out.println("환영합니다." +
            "\n입력 받은 수 까지 2의 배수인지 3의 배수인지 체크합니다!!");

    System.out.print("입력:  ");
    Scanner sc = new Scanner(System.in);
    int input = sc.nextInt();                   // 입력 값 범위 받음

    int j = 2;        int k = 3;                // 알고자 하는 배수의 기준? 수포자 ㅠ

    for (int i = 1; i <= input ; i++) {
        if (i % k == 0 && i % j == 0) {
            System.out.println(i + " -> " + j + " 와 " + k + "의 배수입니다.");    // 공통 배수 노티
        } else if (i % j == 0) {
            System.out.println(i + " -> " + j + "의 배수입니다.");                // j 배수 노티
        } else if (i % k == 0) {
            System.out.println(i + " -> " + k + "의 배수입니다.");                // k 배수 노티
        } else {
            System.out.println(i);                                              // 나머지는 그냥 출력.
        }
    }
}

1부터 입력받은 숫자 사이의 모든 수를 출력하고 2와 3의 배수 여부를 판단한다.

  • 반복문과 조건문은 이전에 하도 고생해서 큰 어려움 없이 작성을 했다.
  • 조금 신경써야하는 부분은 코딩은 위에서 아래로 흐르기 때문에 가장 먼저 처리해야할 것을 제일 위에 작성하는 것이 효율적이다. 만약 공통 배수 노티를 하단부에 적었다면 코드가 좀 더 많이 길어졌을 것이다.

3-1. 이중 배열 작성.ver1

public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {               // i = 행
        for (int j = 0; j < 5; j++) {           // j = 열
            System.out.print(i+j+1);
        }
        System.out.println();
    }
}

출력 값은 이러하다. 기존에 배열과 친하지 않아서 조금 고생을 했다.

 

 

 

 

 

 

 

  • 이중 for문을 사용함에 조금 더 익숙해 진 것 같다. 개념을 조금 더 확실히 잡은 것 같다.
  • 정확하지 않겠지만 나름대로 내린 결론은 배열은 결국 '좌표'라는 것이다.

3-2. 이중 배열 작성.ver2

public static void main(String[] args) {

int [][] arr = new int[5][5];                               // 배열은 좌표라고 생각해라

    for (int i = 0; i < arr.length; i++) {                  // 배열에 값을 입력
        for (int j = 0; j < arr[i].length; j++) {           // i = 행
            arr[i][j] = i;                                  // j = 열
        }
    }

    for (int i = 0; i < arr.length; i++) {                  // 배열을 출력
        for (int j = 0; j < arr[i].length; j++) {           // i = 행
            System.out.print(arr[j][i]);                    // j = 열
        }
    }
}

출력 값은 다음과 같다.

여기서 좀 많은 시간을 사용했다.

 

 

  • 위에서 언급한 대로 배열은 좌표라는 소회를 여기서 확고히했다.
  • 구구단을 만드는 예제를 푼적이 있었는데 그것과 정확히 일치하다는 것을 알고 있음에도 오늘 새로 풀 때는 작성할 줄 몰랐다. 아는 것과 직접 하는 것은 다르다.
  • 가능하면 메서드 하나에는 하나의 기능만을 구현하도록한다. 그래서 for문이 2개이다.

4. 최빈값 구하기

public static void main(String[] args) {
    System.out.println("1~10까지의 수를 5번 입력 받아서 가장 많이 입력된 수를 구하세요!");
    int[] arr = new int[11];       // 담을 배열 생성

    for (int i = 0; i < 5; i++) {
        Scanner sc = new Scanner(System.in);
        System.out.print((i + 1) + "번째 수: ");
        int j = sc.nextInt();
        arr[j] += 1;
    }                                       // 숫자별 입력 횟수 배열로 카운트

        int max = 0;    // 가장 많이 입력된 숫자의 좌표를 확인
        int result = 0;     // 가장 많이 입력된 숫자의 좌표를 추출
    for (int i = 1; i < arr.length; i++) {
        if (max < arr[i]) {
            max = arr[i];
            result = i;
        }
    }
    System.out.println("가장 많이 입력된 수는 "+result);
}

사전 캠프 코딩테스트에서 포기했던 최빈값구하기다. 배열을 사용해서 여전히 어려웠었고 정말 많은 시간을 소요한 것 같다.

  • 이 문제를 푸는 와중에 배열은 좌표라는 것을 망각해서 좀 힘들었었다. 항상 유념하자. 배열은 좌표다.
  • 배열의 기능을 단순히 값들의 묶음이 아닌 다른 형태(카운트)로 바꿔 사용했다. 1번을 입력하면 0번째가 아닌 1번째 배열좌표에 값이 입력되게끔 배열 길이를 11로 생성했다. 약간의 꼼수이다. 그럼에도 배열을 다른 개념으로 사용한다는 것이 좀 신기했고 코딩함에 있어 형식은 엄격히, 사고는 유연히 해야한다는 것을 느꼈다. 오늘 가장 임팩트가 컸던 부분이다.
  • 2번째 for문을 보면 max가 arr배열의 좌표 i에 있는 값(= 입력된 횟수)보다 작으면 arr[i]를 max에 대입한다(=max보다 큰 입력 횟수를 알 수 있다). 그리고 최종적으로 가장 큰 값(=가장 많이 입력된 횟수)의 좌표 i(=숫자)를 result에 대입하고 반복문이 끝나면 그것을 출력한다.
  • 2번째 for문에서 확실히 배운 것은 반복문 안에서 생성한 변수는 반복문 바깥에서 힘을 쓰지 못한다. 그 반대는 힘을 쓴다. 그리고 말로 정리가 안되었지만 배열의 값을 비교하려면 '빈 함수'가 필요하다. 비교하고 값이 더 크다면 따로 빼놓고 다시 비교하는 작업을 이어가야하기 때문이다.

5. ArrayList

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        ArrayList<String> team = new ArrayList<>();         // ArrayList를 생성한다.

        for (int i = 0; i < 4; i++) {                       // 4명의 팀원을 ArrayList에 입력하고자 한다.
            System.out.print("팀원 : ");
            team.add(sc.nextLine());                        // ArrayList에 값을 입력한다.
        }
        for (int i = 0; i < team.size(); i++) {
            System.out.print("팀원 : "+ team.get(i)+"\n");    // ArrayList에 입력된 값들을 출력한다.
        }
            System.out.println("배열의 길이는 : " + team.size()); // ArrayList의 길이를 출력한다.
    }

출력 값은 이러하다.

별 다른 특이사항은 없었고, ArrayList 또한 비교적 많이 사용해본 기능이라서 구현에 큰 문제는 없었다.

 

다만 코드를 짜는 행위와 구현을 하는 과정이 아직 익숙치 않아 숨쉬듯이 매끄럽게 되지는 않았다.

 

 

 

 

 

 

 

6. Stack

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int inputTime = sc.nextInt();                           // 숫자를 몇 번 받을지 설정
    System.out.println("=========================");

    Stack<Integer> stack = new Stack<>();                   // Stack을 생성

    for(int i = 0; i < inputTime; i++) {                    // 설정한 횟수만큼
        int inputNumber = sc.nextInt();                     // 스캐너로 입력 받는데!
        if (inputNumber == 0 ) {                            //조건 1
            stack.pop();
        } else {                                            // 조건2
            stack.push(inputNumber);
        }
    }
    System.out.println(stack.peek());                       // 제일 위에 있는 Stack 확인
}

출력 값이다.

 

Stack은 김장하는 것과 같다. 항아리에 가장 먼저 넣은 김치는 가장 나중에 먹을 수 있다.

반복문과 조건문을 조금 더 익숙해진 것 같다.

 

 

 

 

 

 

 

 

  • Stack에는 .pop 과 .peek 그리고 .push 라는 조금 익숙치 않은 메서드들이 있는데 과거에 작성한 TIL에 자세히 기록되어있다.

7. Queue

    public static void main(String[] args) {
        Queue<Integer> q = new LinkedList<>();      // 큐 생성
        Scanner sc = new Scanner(System.in);        // 값 받기

        System.out.print("카드의 개수는 ");
        int cards = sc.nextInt();
        for (int i = 1; i < cards + 1; i++) {       // 카드 1부터 i까지 카드 설정
            q.add(i);
        }

        System.out.print("몇번 섞으시겠습니까?");
        int shuffle = sc. nextInt();
        for (int i = 0; i<shuffle; i++) {           // i 번 밑장 빼기
            q.add(q.poll());                        // 밑장을 빼면 다시 제일 위로 올라간다.
        }
        System.out.println(q.peek());               // 밑장은 무슨 숫자일까?
    }

출력 값은 이렇다.

Queue는 배관이다. 제일 먼저 들어간 것이 반대쪽에서 제일 먼저 나온다.

 

1 2 3 4 5 가 순서대로 쌓여있는데 밑장을 빼고 다시 제일 위에 보내는 작업을 7번 했다.

그러면 1 2 3 4 5 1 2 3 4 5 이말이기에 제일 밑에는 3이 위치한다.

 

  • Queue는 생성자가 없기에 LinkedList로 생성을 한다(흩어져있는 것들을 땡겨오나?).
  • Queue 또한 Stack과 마찬가지로 조금 특이한 메서드들이 있다.(poll , peek, add, offer...)
  • 밑장을 빼고 다시 제일 위로 올리는 부분인 q.add( q.poll ( ) ); 에서 알 수 있듯이 함께 쓸 수 있다. 이 부분을 몰라서 거의 다 만들고 이상한 길로 많이 샜다. 역시 확실하게 아는 것이 매우 중요하다. 그리고 생각한 것을 일단 한번 시도해보자.

관련글 더보기