프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
나의 풀이
자바스크립트 관점에서 이 문제는 '정규표현식을 조금 쓸줄 아니?', 'sort()함수에 대해서 제대로 이해했니?' 를 묻고싶어서 낸 문제인것 같았다.
이 문제는 HEAD와 NUMBER만 정확히 뽑아내면 된다.
HEAD가 같을 때는 NUMBER로 비교하고 NUMBER도 같다면 return 0을 해서 순서를 유지시켜준다.
문제 풀기전 했던 생각
// 문제
/*
파일명에 포함된 숫자를 반영한 정렬 기능
파일명 100글자 이내
영어 대소문자, 숫자, 공백, 마침표,빼기부호
파일명 영어로 시작, 숫자 무조건 하나 이상 포함
HEAD(최소 1글자 이상) NUMBER(1글자~5글자 앞에 0 올수있 ex 04, 0101)
TAIL 없을 수도 있다.
HEAD 부분을 기준으로 사전 순으로 정렬 대소문자 구분 x(MUZI === muzi === MuZi) -> 다 소문자 만들자
NUMBER HEAD에서 차이가 없을시 숫자 순으로 정렬 0011 < 012 < 014 0은 무시 된다. 012 12 동일함
HEAD와 NUMBER의 숫자도 같을 경우 원래 입력에 주어진 순서를 유지한다.
*/
// 입력
/*
files 1000개 이하 n^2 1,000,000
파일명 100글자 이상
중복된 파일명 x 대신 대소문자 차이는 있을 수 있다.
*/
// 설계
/*
sort로 정렬 콜백함수를 잘짜야한다.
비교할때만 전체 소문자로 해서 비교
HADE로 비교하고 그게 같다면 NUMBER로 비교 그것도 같다면 순서변동(return 0)
*/
전체 코드
function solution(files) {
files.sort((prev, cur) => {
const regexpHead = /\D+/
const regexpNumber = /\d{1,5}/
const prevHead = prev.match(regexpHead)[0]
const curHead = cur.match(regexpHead)[0]
const prevNumber = prev.match(regexpNumber)[0]
const curNumber = cur.match(regexpNumber)[0]
const headCompared = prevHead.toLowerCase().localeCompare(curHead.toLowerCase())
if(isNotSameHead(headCompared)) return headCompared
if(isSameNumber(prevNumber,curNumber)) return 0
return prevNumber - curNumber
})
return files
}
function isNotSameHead(headCompared){
return headCompared !== 0
}
function isSameNumber(prevNumber, curNumber){
return prevNumber - curNumber === 0
}
주의
다 풀고나서 놓친 테스트케이스가 있을 것 같아서 질문하기 게시판을 둘러보다가 발견했다.
files = ["a00000456.png", "a00000123.GIF"]
처음에는 `regexpNumber = /\d+/ 로 잘못 설정하였는데 문제가 통과되었다. 하지만 통과되면 안된다.
해당 예제를 보면
['a', '00000', '456.png']
['a', '00000', '123.GIF']
이렇게 HEAD와 NUMBER가 같기때문에 순서가 유지되어야 하는데
\d+ 로 해버리면 00000456 00000123 을 비교하기때문에 순서가 바뀌게된다.
문제를 꼼꼼히 읽어도 제출전에 다시한번 꼭 체크해야겠다.
if
만약 `-` 기호가 포함되어있지 않았다면 아래처럼 할 수 있다.
function solution(files) {
files.sort((prev, cur) => {
const regexpHead = /\D+\d{1,5}/
const prevHead = prev.match(regexpHead)[0]
const curHead = cur.match(regexpHead)[0]
return prevHead.toLowerCase().localeCompare(curHead.toLowerCase(), "en-u-kn-true")
})
return files
}
`en-u-kn-true` 옵션은 문자는 그대로 비교하고 숫자가 포함되어있으면 숫자값 자체로 비교해준다는 뜻이다.
원래 그냥 우리가 sort 하면 2 10 이렇게 정렬되는 것은 숫자를 문자열로 변환 후 유니코드 값에 따라 정렬되기 때문인데 이를 방지해준다는 이야기다.
ps.
localeCompare
\D
match
'알고리즘 > 프로그래머스 - JS' 카테고리의 다른 글
[프로그래머스] level.2 땅따먹기 (0) | 2023.08.20 |
---|---|
[프로그래머스 - JS] level.2 뒤에 있는 큰 수 찾기 📌⭐️⭐️ (0) | 2023.07.03 |
[프로그래머스] level.2 영어 끝말잇기 (0) | 2023.06.30 |
[프로그래머스] level.2 모음사전 (0) | 2023.06.29 |
[프로그래머스-JS] level.2 스킬 트리 (0) | 2023.06.28 |