문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
strings는 길이 1 이상, 50이하인 배열입니다.
strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
모든 strings의 원소의 길이는 n보다 큽니다.
인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
strings | n |
---|---|
["sun", "bed", "car"] | 1 |
["abce", "abcd", "cdx"] | 2 |
입출력 예 1
"sun", "bed", "car"의 1번째 인덱스 값은 각각 "u", "e", "a" 입니다. 이를 기준으로 strings를 정렬하면 ["car", "bed", "sun"] 입니다.
입출력 예 2
"abce"와 "abcd", "cdx"의 2번째 인덱스 값은 "c", "c", "x"입니다. 따라서 정렬 후에는 "cdx"가 가장 뒤에 위치합니다. "abce"와 "abcd"는 사전순으로 정렬하면 "abcd"가 우선하므로, 답은 ["abcd", "abce", "cdx"] 입니다.
function solution(strings, n) {
return strings.sort().sort((a,b) => a[n]< b[n] ? -1 : a[n] > b[n] ? 1 : 0);
}
sort()
를 두 번 써 줬다. n번째 문자열이 중복이면 사전순으로 정리해 줘야 하기 때문에 아예 처음부터 sort()
를 이용하여 사전순으로 정리한 다음, 두번째 sort()
로 n번째 알파벳의 순서에 따라 분류해 줬다.
여기서 고민한 지점은 두 번째 sort()
안의 함수를 삼항 연산자로 쓸 지 말지였는데, 삼항연산자를 중첩해 써 줘야 했기 때문이다. 삼항 연산자를 중첩해서 쓰는 것에 대해 부정적인 의견이 많지만, 이 문제는 짧기 때문에 그냥 삼항 연산자를 쓰는 게 if문을 쓰는 것보다 가독성이 나아 보였다.
return strings.sort().sort((a,b) => function compare(a,b){
if (a[n] < b[n])
return -1;
else if (a[n] > b[n])
return 1;
else
return 0;
};
하지만 코드가 길고, 같이 일하는 팀원이 부정적이라면 if문을 쓰는 것도 고려해야 할 듯 하다.
function solution(strings, n) {
// strings 배열
// n 번째 문자열 비교
return strings.sort((s1, s2) => s1[n] === s2[n] ? s1.localeCompare(s2) : s1[n].localeCompare(s2[n]));
}
여기서는 비교할 때, localeCompare()
함수를 써 줬다. 이 함수는 원래 ASCII이외의 문자, 즉, 악센트같은 문자까지 정렬하게 해 준다. sort()
는 기본으로 영어 순서대로 정렬하지만 localeCompare()
는 옵션을 줘서 어떤 문자인지 지정을 해 주는 것이다. 이 풀이에서는 sort()
안에 비교를 해주는 함수를 넣으면 길어지니까 localeCompare()
을 써준 듯 하다.
기본적인 알고리즘은 이렇게 이루어진다. 첫 번째 문자와 두 번째 문자의 n자리수를 비교한 후 같다면 전체 문자열을 비교해주고 다르다면 n자리만 비교해 준다.
function solution(strings, n) {
return strings.sort((a, b) => {
const chr1 = a.charAt(n);
const chr2 = b.charAt(n);
if (chr1 == chr2) {
return (a > b) - (a < b);
} else {
return (chr1 > chr2) - (chr1 < chr2);
}
})
}
이 풀이는 특이해서 들고 왔다. 일단 sort()함수를 기본으로 정렬을 하는데, 조건을 줘서 정렬한다. charAt()함수는 특정 인덱스의 문자를 반환하는 함수이다. a[n]과 동일하다. 그래서 만약 n번째 문자열이 같다면 문자열 전체를 비교하고, 다르다면 문자열의 n번째 문자를 비교해 준다.
여기에서 sort()의 정렬 기준 함수를 한 줄로 써줬다. 그것이 (a>b) - (a<b)이다. sort()함수의 원래 정렬 함수는 function compare(a, b)
{
if (a is less than b by some ordering criterion) {
return -1;
}
if (a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
아래와 같다. a<b라면 -1를 반환해 a를 앞으로 정렬해 주고, a>b라면 1을 반환해 b를 앞으로 정렬해 준다. a=b라면 0을 반환해 순서를 정렬하지 않는다. 이 함수를 한 줄로 써 준 것이다.
javascript에서 true는 1, false는 0이므로 a>b라면 1-0 = 1을 출력한다. a<b라면 0-1 = -1을 출력한다. a=b라면 0을 출력한다. 이렇게 원래의 함수랑 똑같은 내용으로 작동하는 값을 함수를 사용하지 않고 return값으로 준 것이다.