휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.
예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.
같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.
이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.
1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.
단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.
keymap = ["ABACD", "BCEFD"], targets = ["ABCD","AABB"] -> [9,4]
targets을 먼저 이중반복문을 돌려 targets[0][0]부터 문자열을 확인한 뒤 checkStr에 할당
checkStr 문자열과 일치하는 문자열을 keymap에서 찾으려면 keymap에서 반복문으로 먼저 인덱스에 접근한뒤 indexOf('확인문자')
있는 요소들중 확인문자랑 같은 문자열이 앞쪽에 있는 요소의 인덱스 + 1 을 resultCount에 더해준다.
checkStr과 일치하는 문자열이 keymap에 없다면 -1을 resultCount에 할당하고 리턴
function solution(keymap, targets) {
const resultArr = [];
for(let i = 0; i < targets.length; i++){
let count = 0; // targets[i]의 최소 클릭 횟수
for(let j = 0; j < targets[i].length; j++){
// targets[i][j]의 문자열이 keymap의 요소의 문자열에 있는 요소들로만 이루어진 배열
let checkEle = keymap.filter((el) => {
return el.indexOf(targets[i][j]) !== -1;
});
// targets[i][j]의 문자열이 keymap의 요소의 문자열에 존재하지 않을때 count에 -1을 할당시키고 break 키워드로 반복문 탈출!
if(checkEle.length === 0){
count = -1;
break;
}
// target[i][j]를 keymap의 요소마다 접근한 클릭 횟수를 나타낸 배열
let checkEleCount = checkEle.map((el) => {
return el.indexOf(targets[i][j]) + 1;
});
// checkEleCount의 클릭 횟수가 가장 최소값인 값을 reduce매서드로 빼오기.
let comparisonCount = checkEleCount.reduce((a,b) => {
if(a > b){
a = b;
}
return a;
});
count += comparisonCount; // targets[i][j]의 최소 클릭 횟수를 count에 더해준다. 그리고 다시 targets[i][j + 1]로 반복시작.
}
resultArr.push(count);
}
return resultArr;
}
처음에 너무 복잡하게 코드를 생각했기 때문에 어려웠지만,
의사코드를 쓰고 코드를 쓰다보니 고차함수(map,filter,reduce)함수가 딱 떠올라서 고차함수를 써보았다.
reduce매서드의 초기값을 어떻게 줘야할지가 가장 고민이었다.
이유는 초기값을 줘버리면 가장 최소 값이 초기값으로 할당되기만 해서 문제가 되기 때문이었다.
초기값을 주기 애매하다면 다른 방법을 써보자는 생각에
애초에targets[i][j]
가 keymap에 존재하지 않을때count = -1
을 할당시키고break
키워드를 써서 반복문을 탈출 시키는 방법으로 해결하였다.