[프로그래머스] 문자열 내 마음대로 정렬하기
2022.01.08에 푼 문제입니다.
제가 푼 방식이 너무 별로라서 다른 사람 풀이로 써져 있는 걸로 설명해보려고 해요.
이 문제는 조건에 맞게 정렬을 어떻게 하는지에 대한 문제라
sort()메서드에 대한 이해가 있어야 풀 수 있는 문제인 것 같아요.
안 그러면 저처럼 sort에 대해 어중간하게 알면 돌고 돌아서 풀어야 돼요.😅
이번 해결방안에 sort를 잘 사용한 예와 아닌 예를 보여주면 좋을 것 같아서 제가 푼 방법 코드도 올리겠습니다.
sort() 메서드를 잘 사용하지 못한 예
function solution(strings, n) {
var answer = [];
strings.sort();
let alpabes = strings.map(x =>x.charAt(n)).sort();
for(let i=0; i<alpabes.length; i++){
for(let j=0; j<strings.length; j++){
if(strings[j].charAt(n) === alpabes[i]){
answer.push(strings[j]);
strings.splice(j, 1);
break;
}
}
}
return answer;
}
요건 굳이 설명 안 해도 될 것 같아서 설명 안 하겠습니다.~
다들 그냥 스쳐지나가세요ㅠㅠ
해결방안 : sort() 메서드를 잘 사용한 예
function solution(strings, n) {
strings.sort((a,b)=>{
if(a[n] > b[n]) return 1;
if(b[n] > a[n]) return -1;
if(a > b) return 1;
if(b > a) return -1;
return 0;
});
return strings;
}
해결방안 순서
- strings배열의 원소(단어)의 n번째자리 기준으로 오름차순으로 정렬
- strings배열의 원소(단어)의 n번째자리 알파벳 같은 경우 원소(단어)의 사전 순으로 정렬해줍니다.
이번 문제는 sort()메서드를 쓸 때 하나의 값을 기준으로 정렬합니다.
compare함수의 형식을 쓰는 이유는 정렬해야 되는 배열이 숫자가 아니라 문자이기 때문에
이럴 경우에는
- sort((a,b)=>a-b); -> 오름차순
- sort((a,b)=>b-a); -> 내림차순
이 적용이 안되서 compare함수를 사용합니다.
이번 문제는 sort()메서드의 하나의 값을 기준으로 정렬하는 방법에 대한 설명 전부라서
전에 프로그래머스 실패율 해결방안에서 sort()를 보시면 좋을 것 같습니다.👇
https://development-piece.tistory.com/7
[프로그래머스] 실패율
2021.10.25에 푼 문제입니다. 이번에도 역시나... 잘 안 풀려서ㅠ 남친님한테 SOS해서 풀었습니다.😂 남친님이 치는 코드 보면 존경스러워요ㅠㅠ 너무 잘해요. 그냥 봐도 이해가 되고 자바스크립트
development-piece.tistory.com
그래도 여기서 또 한 번 설명하면 좋을 것 같아서 다시 한번 설명해보겠습니다.
MDN Web Docs
sort() 메서드는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환합니다.
구문 : arr.sort([compareFunction])
- compareFunction Optional : 정렬 순서를 정의하는 함수. 생략하면 배열은 각 요소의 문자열 변환에 따라 각 문자의 유니 코드 코드 포인트 값에 따라 정렬됩니다.
간단하게 얘기하면
구문 : 배열.sort(정렬 순서를 정의하는 함수)
// compare함수의 형식
function compare(a, b) {
if (a는 일부 주문 기준에 의해 b보다 작습니다.) {
return -1;
}
if (a는 순서 기준에 의해 b보다 큽니다.) {
return 1;
}
// a는 b와 같아야 합니다.
return 0;
}
sort() 메서드를 정렬할 때 문자열 대신 숫자를 비교하기 위해 compare 함수는 a에서 b를 뺄 수 있습니다.
- sort((a,b)=>a-b); -> 오름차순
- sort((a,b)=>b-a); -> 내림차순
var numbers = [4, 2, 5, 1, 3];
// sort()메서드로 오름차순
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers); // [1, 2, 3, 4, 5]
// sort()메서드로 내림차순
numbers.sort(function(a, b) {
return b - a;
});
console.log(numbers); // [5, 4, 3, 2, 1]
이렇게 a, b를 넣어주면 차례대로 배열의 원소들을 비교하게 됩니다.
쉽게 설명하면 sort((next, prev)=>{});로 생각하시면 됩니다.
그러나 이번 문제에서는 숫자를 정렬하는 것이 아닌 문자열을 정렬하기 때문에 sort를 compare 함수의 형식으로 써서
하나의 값을 기준으로 정렬해보겠습니다.
오름차순
// 오름차순
let strings = ["car", "bed", "sun"];
strings.sort(function (a, b) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
});
console.log(strings); // ["bed", "car", "sun"]
내림차순
// 내림차순
let strings = ["car", "bed", "sun"];
strings.sort(function (a, b) {
if (a < b) return 1;
if (a > b) return -1;
return 0;
});
console.log(strings); // ["sun", "car", "bed"]
여기서 주의해야 될 점과 알아야 되는 점은
- 오름차순과 내림차순에 대한 기준은 변경의 return -1에서만 일어납니다.
- if() return -1를 써주면, if() return 1도 세트로 같이 써주어야 됩니다.
- 꼭 return 1; return -1; return 0;를 다 써야 됩니다.
오름차순과 내림차순에 대한 기준은 변경의 return -1에서만 일어납니다.
- if (a < b) return -1; :오름차순
- if (a > b) return -1; : 내림차순
if() return -1를 써주면, if() return 1도 세트로 같이 써주어야 됩니다.
- 오름차순
if (a > b) return 1;
if (a < b) return -1; - 내림차순
if (a < b) return 1;
if (a > b) return -1;
여기까지 sort()메서드에 대한 설명이었고요.
저는 아래 있는 블로그도 참고해서 적었는데요. sort()메서드에 대해 자세히 알고 싶으시다면 아래 링크에서 확인하시면 됩니다.👇
Javascript Sort함수에 대한 잡지식
javascript sort 함수는 당신이 원하는대로 동작하지 않을 것이다. (만일 당신이 비교 함수를 작성하지 않는다면)
velog.io
본론으로 돌아와서 해결방안에 대해 설명하겠습니다.
1단계. strings배열의 원소(단어)의 n번째자리 기준으로 오름차순으로 정렬
// 1단계. strings배열의 원소(단어)의 n번째자리 기준으로 오름차순으로 정렬
if(a[n] > b[n]) return 1;
if(b[n] > a[n]) return -1;
먼저 strings 배열의 원소에서 n번째자리 기준으로 오름차순을 정렬해야 되는데요.
배열의 원소의 n번째가 무엇인지를 코드로 나타내면
테스트1로 설명 : strings = ["sun", "bed", "car"]; n = 1;
- strings[0][n] -> strings[0][1] -> u
- strings[1][n] -> strings[1][1] -> e
- strings[2][n] -> strings[2][1] -> a
이렇게 됩니다.
앞에서 sort()메서드의 a, b는 배열의 원소라고 했습니다.(a는 next, b는 prev)
그래서 sort()메서드 안에서는 배열의 원소의 n번째가 무엇인지를 코드로 나타내면
- a[n]
- b[n]
이렇게 됩니다.
여기서 strings 배열의 원소에서 n번째 자리 기준으로 오름차순을 정렬해야 됨으로
if(a[n] > b[n]) return 1;
if(b[n] > a[n]) return -1;
이렇게 됩니다.
테스트1 : strings = ["sun", "bed", "car"]; n = 1;
sun의 n번째자리 -> u
bed의 n번째자리 -> e
car의 n번째자리 -> a
[car, bed, sun]
테스트2 : strings = ["abce", "abcd", "cdx"]; n = 2;
abce의 n번째자리 -> c
abcd의 n번째자리 -> c
cdx의 n번째자리 -> x
[abce, abcd, cdx]
2단계. strings배열의 원소(단어)의 n번째자리 알파벳 같은 경우 원소(단어)의 사전 순으로 정렬해줍니다.
// 2단계. strings배열의 원소(단어)의 n번째자리 알파벳 같은 경우 원소(단어)의 사전순으로 정렬해줍니다.
if(a > b) return 1;
if(b > a) return -1;
테스트 1에서는 strings배열의 원소(단어)의 n번째자리 알파벳이 다 달라서 구할 수 있지만
테스트 2에서는 strings배열의 원소(단어)의 n번째자리 알파벳이 같은 경우가 있어 이때는 원소(단어)의 사전 순으로 정렬해주어야 됩니다.
sort()메서드안에는 하나의 기준이 아닌 여러 개의 기준을 넣어줄 수가 있습니다.
그래서 이번에는
if(a[n] > b[n]) return 1;
if(b[n] > a[n]) return -1;
을 넣어주고
그 밑에다가
if(a > b) return 1;
if(b > a) return -1;
을 넣어 주었습니다.
이럴 경우 첫 번째 기준의 정렬을 수행한 뒤에 다음 두 번째 정렬 기준의 정렬이 수행하게 됩니다.
- if(a[n] > b[n]) return 1;
if(b[n] > a[n]) return -1; - if(a > b) return 1;
if(b > a) return -1;
이런 순으로 진행하게 됩니다.
여기서는 "원소(단어)의 사전 순으로 정렬해주어야 됩니다."으로 정렬해 주어야 된다고 했으니
a, b로만 비교해서 넣어주었습니다.
테스트 1 : strings = ["sun", "bed", "car"]; n = 1;
1단계.
sun의 n번째자리 -> u
bed의 n번째자리 -> e
car의 n번째자리 -> a
[car, bed, sun]
2단계
이미 첫번째 정렬에서 완료됐음으로 1단계에서 나온 strings을 그대로 반환
테스트 2 : strings = ["abce", "abcd", "cdx"]; n = 2;
1단계.
abce의 n번째자리 -> c
abcd의 n번째자리 -> c
cdx의 n번째자리 -> x
[abce, abcd, cdx]
2단계
abce의 n번째자리(c)와 abcd의 n번째자리(c)가 같음으로 2번단계에서 다시 정렬합니다.
abce보다 abcd이 사전적 순으로는 앞임으로
[[abcd, abce, cdx]] 됩니다.
여기까지 프로그래머스 문자열 내 마음대로 정렬하기 해결방안에 대해 설명해보았습니다.