
아래 프로그래머스 로고를 클릭하면 해당 문제로 이동합니다 😀
문제 보자마자 정규식 쓰는 문제구나 .. 분할해야하는 부분을 체크했다.
문제에서 주어진 조건은 다음과 같다.
HEAD + NUMBER + TAIL로 구성HEAD를 기준으로 대소문자 구분 없이 정렬HEAD가 같다면 NUMBER를 기준으로 정렬(숫자 크기 비교)그러면 어떻게 풀어가야하는가 ?
각 언어에 맞게 코드 위에 설명을 작성해놨다!
정규표현식은 동일하니 여기 ,, 적어두겠다.
파일명을 HEAD, NUMBER, TAIL로 나누자. 정규표현식을 사용하면 된다.
여기서 사실 TAIL은 정렬 조건에 포함되지 않기 때문에 무시해도 된다.
- HEAD: 숫자가 아닌 문자 하나 이상(([^\d]+))
- NUMBER: 숫자 1~5자리((\d{1,5}))
head.lower(), int(number)을 이용해 대소문자 무시를 위한 소문자 처리와 숫자 정렬을 위한 숫자 변환 하여 튜플로 리턴한다.
이후, sorted() 함수를 이용해 parse_file(file)이 리턴한 튜플 (head, number)를 기준으로 정렬한다.
import re
def solution(files):
def parse_file(file):
match = re.match(r"([^\d]+)(\d{1,5})", file)
head, number = match.groups()
return (head.lower(), int(number))
return sorted(files, key = parse_file)
JS에서는 python의 sorted처럼 짧게 코딩이 안되기 때문에 sort() 함수에 직접 비교 함수를 넣어줘야 한다.
정규식을 이용해 HEAD, NUMBER를 나누고 나서
HEAD를 소문자로 변환한 후 직접 비교를 통해 사전순으로 정렬하고,
HEAD가 같을 경우 NUMBER를 정수로 변환해 크기비교를 한다.
function solution(files) {
return files.sort((a, b) => {
const regex = /^([^\d]+)(\d{1,5})/;
const [, headA, numA] = a.match(regex);
const [, headB, numB] = b.match(regex);
const [lowerHeadA, lowerHeadB] = [headA.toLowerCase(), headB.toLowerCase()];
if(lowerHeadA < lowerHeadB) return -1;
if(lowerHeadA > lowerHeadB) return 1;
return +numA - +numB;
});
}
