[코드트리 조별과제 1주차 코딩테스트 연습] 배열 놀이 문제 풀이 with 자바스크립트(Javascript) & 자바(Java)

Re_Go·2024년 7월 15일
0

코딩테스트연습

목록 보기
99/106
post-thumbnail

1. 첫번째 문제 풀이(2024-07-15)

해당 문제의 경우 조건문을 이용해서 푸는, 생각보다 간단한 문제이긴 했는데요.

문제는 코드트리 문제가 백준 제출 양식과 비슷하다보니... 여지껏 프로그래머스로 풀어오다 오랜만에 푸는 코드트리 문제를 풀려니 적응이 안되서 꽤 애를 먹은 문제였습니다 😥 특히 주어지는 입력 부분에서 더 애를 먹었던 것 같아요... (진심 30분 동안 문제만 뚫어지게 본...)

그도 그럴것이, 작년 9월 말 부터 꽂혀서 한 달 동안 열심히 한창 풀다가, 병원에 입원하는 바람에 재활 치료를 해야만 했고, 또 적응이 되어서 다시 도전해보려 했더니 요금제 때문에... (학생 할인을 받아서 싼 가격에 살 순 있기는 한데 기초생활수급비를 받고 있는 상황이라 부담이 이만 저만 아닌....) 그래서 나름의 사정 때문에 한동안 손에 놓고 있었는데 이번에 블로그 이벤트 덕분에 기간 한정 무료로 문제를 풀수 있게 되었답니다! (물론 기간이 지나면 또 막히겠지만 그 안에라도 열심히 풀어야지 뭐...)

작년 블로그 이벤트 할 때 병원 입원 전 까지 한창 했었네요...

그래도 그 때는 꽤 많이 풀었군요...?

게다가 깃허브랑 연동도 되서 문제를 풀때마다 자동 커밋도 되고, 또 코드트리 전용 UI도 있더군요? 그래서 오랜만에 삘받아서 많이 좀 풀었습니다... 허허허 (당분간 코드트리로 연습을...)

잡설이 좀 길었는데, 아무튼 입력 방식만 이해하면 되는 문제인지라 이 부분이 해결된 덕에 그 이후로는 무리 없이 풀 수 있는 문제였고, 주어지는 테스트 케이스 (1,2,3)에 따라 코드가 갈리다보니 switch문을 쓸까도 생각을 했는데, 그냥 안전하게 for문을 쓰기로 했습니다.

그럼 다음으로 해당 문제에 대한 자바스크립트 풀이 코드를 보여드리겠습니다.

  1. 자바스크립트 버전
const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

let arr = [];
let firstLine = input[0].split(' ').map(Number);
let testCase = firstLine[1];

/*입력 형식에서 햇갈렸긴 했는데, 얼추 생각을 해본것은
첫번째 줄 : n개의 원소와 q개의 테스트 케이스
두번째 줄 : n개의 원소가 순서대로 나열
세번째 줄 부터 : 첫번째 원소는 1부터 3까지의 테스트 케이스, 두번째 부터는 각각의 1의 a, 2의 b, 3의 s와 e의 요소입니다.
*/

arr = input[1].split(' ').map(Number);

// 범위는 2부터 시작해 input.length까지 돌아도 상관 없습니다.
for(let i = 2 ; i < testCase + 2 ; i++){
    // 각 쿼리마다 숫자로 바꿔주고 공백을 기준으로 나눠서 배열로 반환 받기
    let query = input[i].split(' ').map(Number);
    // 테스트 케이스가 1이면 a번째 (a-1)를 출력
    if(query[0] == 1){
        console.log(arr[query[1] - 1]);
        continue;
    }
    if(query[0] == 2){
        // 테스트 케이스가 2이면 indexOf가 존재할 때 b의 인덱스의 위치 + 1(0부터 시작하므로) 를 반환받음. 
        let letter = arr.indexOf(query[1]) == undefined ? 0 : arr.indexOf(query[1]) + 1 
        console.log(letter)
        continue;
    }
    if(query[0] == 3){
        // 테스트 케이스가 3이면 시작값과 종료값을 정하고, 공백으로 배열(arr)의 요소들을 join으로 문자열로 합친 뒤 arr에서 slice로 잘라서 범위만큼 잘라 반환
        let startPoint = query[1] - 1;
        let endPoint = query[2];
        let letter = arr.slice(startPoint, endPoint).join(' ');
        console.log(letter);
        continue;
    }
}

그리고 자바 버전으로 구현한 코드는 다음과 같습니다.

  1. 자바 버전
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        // 첫 번째 줄 입력 받기
        st = new StringTokenizer(br.readLine());
        // 배열 길이
        int n = Integer.parseInt(st.nextToken());
        // 테스트 케이스 수
        int q = Integer.parseInt(st.nextToken());

        // 두 번째 줄 입력 받기 (배열 원소)
        int[] arr = new int[n];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        // 쿼리 처리
        for (int i = 0; i < q; i++) {
            st = new StringTokenizer(br.readLine());
            int type = Integer.parseInt(st.nextToken());
             // 테스트 케이스1인 경우 다음 토큰 번째 요소 출력
            if (type == 1) {
                int a = Integer.parseInt(st.nextToken());
                System.out.println(arr[a - 1]);
             // 테스트 케이스 2인 경우
            } else if (type == 2) {
                int b = Integer.parseInt(st.nextToken());
                // list를 하나 선언하고 배열길이 n만큼 돌면서 arr[j] 번째 요소가 b와 같다면 해당 인덱스를 의미하는 j + 1을  list에 add하고, for문이 끝난 뒤 list가 비어있는 경우(하나도 없는 경우)는 0, 아니라면 list의 가장 첫번째 발견 원소 위치를 출력
                List<Integer> list = new ArrayList<>();
                for (int j = 0; j < n; j++) {
                    if (arr[j] == b) {
                        list.add(j + 1);
                    }
                }
                if (list.isEmpty()) {
                    System.out.println(0);
                } else {
                    System.out.println(list.get(0));
                }
             // 테스트 케이스가 3인 경우
            } else if (type == 3) {
            	// 시작 인덱스 (-1를 해야 인덱스가 옳게 감)
                int s = Integer.parseInt(st.nextToken()) - 1;
                // 범위 인덱스 (그대로 담아야 그 전 까지 범위로 잡을 수 있음)
                int e = Integer.parseInt(st.nextToken());
                // 쉽게 어펜드를 해주기 위해 String Builder 객체 생성
                StringBuilder sb = new StringBuilder();
                // for문이 도는 동안 각 j의 요소를 appened
                for (int j = s; j < e; j++) {
                    sb.append(arr[j]);
                    // 배열의 각 요소 안에 공백 넣기, e와 같아지는 시점에는 공백을 안 넣음.
                    if (j < e - 1) {
                        sb.append(" ");
                    }
                }
                System.out.println(sb.toString());
            }
        }
    }
}
}

2. 자바와 자바스크립트 풀이 차이점

  1. 코드트리에 JS는 입력을 받을 때 fs모듈로 파일을 읽어와야 했습니다. 뭐 익숙하진 않지만 그래도 양식이 있으니... 그리고 자바의 경우 편하게 스캐너를 받으면 이전에 사용하던 BufferedReader랑 InputStreadReader, StringTokenizer 조합을 사용해서 문자열을 처리해 봤습니다. 특히 버퍼의 readLine과 토큰의 nextToken메서드로 편안하게 꺼내 써먹을 수 있었습니다.

  2. JS의 경우 indexOf와 trim을 이용해서 쉽게 데이터를 정제했지만, 자바의 경우 왠지 타입 별로 쓸 수 있는 메서드가 달라서 그냥 정공법으로 뚫어봤습니다. 그래서 테스트 케이스2의 경우 스택(list)로 한 번 해봤고, 테스트 케이스3의 경우 공백 제거 메서드 보다 증가값을 이용해 공백을 넣어주는 방식을 사용했습니다. 그 덕에 JS보다 한 시간 가까이 문제를 풀어야 했습니ㄷ...

오늘의 코딩테스트 연습 끝~

profile
인생은 본인의 삶을 곱씹어보는 R과 타인의 삶을 배워 나아가는 L의 연속이다.

0개의 댓글