[프로그래머스 코딩테스트 연습문제] 대충 만든 자판 문제 풀이 with 자바스크립트(Javascript) & 자바(Java)

Re_Go·2024년 7월 10일
0

코딩테스트연습

목록 보기
97/98
post-thumbnail
post-custom-banner

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

해당 문제는 꽤나 까다로워서 애를 먹긴 했지만, 함수를 따로 만들어서 문제를 풀었는데요. 일단 문제 풀이를 위한 절차를 설명해보면 다음과 같습니다.

  • keymap의 문자열들 중 targets의 문자들 각각에 최소한으로 타이핑 할 수 있는 문자열을 찾는다. (이 과정에서 최소값을 구하는 과정이 필요하다)
  • keymap의 문자열들 중 targets의 특정 문자를 하나라도 찾을 수 없을때에는 -1를 반환한다. (하나라도 찾을 수 없다면 targets의 해당 문자열 자체를 완성하지 못하기 때문)

그래서 해당 문제를 커스텀 함수 및 플래그 루프를 이용하여 풀어보았는데요. 알고리즘 설명은 다음 그림을 참조 부탁드립니다!

  1. 최소 문자 타이핑 횟수를 구하는 함수

(자료 출처 : 미리캔버스로 제작했습니다.)

이때 경우의 수를 생각해야 하는데요. 그건 바로 함수에서 반복문을 돌면서 targets의 특정 문자열의 문자를 keymap의 문자열들에서 찾을 수 없는 경우, 즉 indexOf 메서드를 사용했을 때 -1을 반환 받았을 때의 경우입니다.

그래서 함수에서 keymap만큼 for문을 도는 동안 문자열 마다 indexOf메서드로 letter의 위치를 찾을 때 -1을 반환 받는 경우, 즉 해당 문자열에 찾고자 하는 문자가 없을 때는 다음 for문으로 이어가도록 처리를 해야합니다. 이 말인 즉 반환 받은 값이 -1이 아닐 때 Math.min으로 해당 문자열의 인덱스 + 1값과 minPress의 값을 비교하여 작은 값을 minPress에 할당하는 코드가 실행되도록 해야한다는 것이죠. 바로 아래의 코드처럼요.

// 키맵 길이만큼 반복
for(let i = 0; i < keymap.length; i++){
  // 문자열 마다 문자의 최소길이를 구함
  let index = keymap[i].indexOf(letter);
  // 만약 최소 길이가 -1가 아닌 경우, 즉 찾은 경우라면 아래의 코드를 실행해 최소값을 구함
  if(index !== -1) {
    minPress = Math.min(minPress, index + 1); // 최소 값을 찾음
  }
}

두번째는 문자열을 다 돌아도 해당 문자열이 없는 경우, 즉 minPress가 초기의 값인 Infinity일때입니다. 아시다시피 최소값을 구하는 기본 공식은 처음 비교값으로 Infinity(가장 큰 값)을 할당한 변수와 다른 변수의 값을 비교해 작은 값을 Infinity가 담긴 변수에 할당하는 방식인데요. 모르시는 분들을 위해 아래의 코드를 잠깐 소개해 드릴테니 한 번 코드 과정을 생각해 보시면 좋을 듯 합니다!

let arr = [1,2,3,4,5,6,7,8,9,10];
// JS에서 가장 큰 값을 최소값을 담을 변수에 초기화
let minNum = Infinity;
// JS에서 가장 작은 값을 최대값을 담을 변수에 초기화
let maxNum = -Infinity;
for(let i = 0 ; i < arr.length ; i++){
  if(arr[i] < minNum) minNum = arr[i];
  if(arr[i] > maxNum) maxNum = arr[i];
}
console.log(`최소값은 ${minNum} 입니다.`);
console.log(`최대값은 ${maxNum} 입니다.`);

이제 본문으로 돌아와서, 함수에서 minPress의 값이 초기에 할당했던 Infinity 값이라는건 keymap의 그 어느 문자열도 해당 문자를 처리할 수 없는 상태라는 뜻이므로 -1를 반환하도록 해야하는거죠.

return minPress === Infinity ? -1 : minPress;

이것만 해주시면 그 아래 코드는 그리 큰 어려움이 아니므로 해당 문제를 JS 버전으로 푼 코드를 소개해 드리면서 주석으로 설명해 드리겠습니다!

2. 코드 소개 및 풀이(주석)

  1. 자바스크립트 버전
function solution(keymap, targets) {
    let result = [];

    function countButtonPressingNumber(letter) {
        let minPress = Infinity; // 최소 키 누름 횟수를 무한대로 초기화
        for(let i = 0; i < keymap.length; i++){
            let index = keymap[i].indexOf(letter);
            if(index !== -1) {
                minPress = Math.min(minPress, index + 1); // 최소 값을 찾음
            }
        }
        return minPress === Infinity ? -1 : minPress;
    }

  	// for문을 targets만큼 돌리면서 각 버튼을 누른 횟수를 합산하 count와 플래그 루프 사용을 위한 flag 변수를 false로 할당
    for(let i = 0; i < targets.length; i++){
        let count = 0;
        let flag = false;
      	// for문을 다시 targets의 각 문자열의 길이만큼 돌리면서 각 문자들을 위에서 선언한 함수에 넘겨주고 최소값을 반환받음
        for(let j = 0; j < targets[i].length; j++){
            let ctn = countButtonPressingNumber(targets[i][j]);
          	// 만약 반환받은 값이 -1, 즉 최소값을 찾지 못했다면 flag를 true로 바꾸고 for문 종료
            if(ctn === -1){
                flag = true;
                break;
            // -1이 아닐경우 count에 차곡차곡 담아줌
            } else {
                count += ctn;
            }
        }
      	// 해당 문자열에 대해 flag가 발생 된 경우, 즉 문자열 중 최소값을 찾지 못한 문자가 존재하면 문자열을 온전히 완성할 수 없으므로 result 배열에 -1를 할당
        if(flag) result.push(-1);
      	// 그게 아니라면 result 배열에 누적된 count(문자열 완성을 위해 누른 최소 버튼수)를 할당
        else result.push(count);
    }
  	// targets의 for문이 다 끝났다면 최종적으로 result를 반환
    return result;
}

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

  1. 자바 버전
import java.util.ArrayList;
import java.util.List;

public class Solution {
    
    public static List<Integer> solution(String[] keymap, String[] targets) {
        List<Integer> resultList = new ArrayList<>();
     
        for (String target : targets) {
            int count = 0;
            boolean flag = false;

            for (int j = 0; j < target.length(); j++) {
                int ctn = countButtonPressingNumber(keymap, target.charAt(j));
                if (ctn == -1) {
                    flag = true;
                    break;
                } else count += ctn;
            }

            if (flag) resultList.add(-1);
            else resultList.add(count);
        }
        return resultList;
    }

    public static int countButtonPressingNumber(String[] keymap, char letter) {
        int minPresses = Integer.MAX_VALUE; // 최소 키 누름 횟수를 매우 큰 값으로 초기화

        for (String key : keymap) {
            int index = key.indexOf(letter);
            if (index != -1) {
                minPresses = Math.min(minPresses, index + 1); // 최소 값을 찾음
            }
        }
        return minPresses == Integer.MAX_VALUE ? -1 : minPresses;
    }
}

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

  1. JS의 경우에서 양의 무한대와 음의 무한대 값으로 Infinity와 -Infinity, 즉 쉽게 생성 가능한데요. 자바의 경우 Integer 래퍼 클래스의 상수 필드인 MAX_VALUE와 MIN_VALUE를 사용해야 합니다.

  2. JS의 경우 인덱스의 접근이나 반환등의 방법이 쉬운 반면, 자바의 경우 타입을 지정하고 클래스 메서드로 변환해서 접근하거나 반환해야 하므로 은근 신경쓸 부분이 제법 있었습니다.

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

0개의 댓글