알고리즘/프로그래머스

[프로그래머스/Swift] 파일명 정렬

녕이 2023. 1. 7. 18:55
728x90

 

https://school.programmers.co.kr/learn/courses/30/lessons/17686

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문자열 구현 문제!

 

간단히 문제를 정리해 보면

코드 순이 아닌, 파일명에 포함된 숫자를 반영한 정렬기능 구현하기

HEAD: 숫자가 아닌 문자로 이루어지고, 최소 한 글자 이상

NUMBER: 1~5 연속된 숫자. 00000-99999

TAIL: 나머지 부분. 숫자 혹은 아무 글자가 없을 수도 있음

이렇게 3가지로 나눈 후, 파일명을 정렬한다. 윗 조건이 같을 경우 밑 조건 ㄱㄱ

1. HEAD 기준으로 먼저 사전순 정렬 (대소문 구분 x)

2. NUMBER 숫자순 정렬

3. 원래 입력에 주어진 순서 유지.

 

여기서 HEAD, NUMBER만 필요하고 TAIL은 필요 없다.

숫자가 처음으로 시작되는 index(numberStartIndex1/2)를 찾고

끝나는 index(numberEndIndex1/2)를 찾았다.

그 후, head와 number에 각 문자열을 넣어줬다. 그 후 정렬 조건을 맞춰서 구현!

 

 

 

🚨 이슈 3가지

 

1. 정렬 시 원본 그대로 두려면 어떻게..?

return 값으로 배열을 정렬하는데 원본 그대로 두려면 == 를 사용한다. 혹시나 해서 해봤는데 잘 돼서 놀랐다ㅎ 이렇게 하는 것이군~

 

2. TAIL이 없는 경우!!

이 부분을 생각하지 않아서 2번이나 실패했는데, 사실 이건 문제만 잘 봐도 생각할 수 있는 조건이었다ㅠ.ㅜ

숫자의 시작 index부터 시작해서 문자가 나오면 그 인덱스를 end index로 구했는데 문자가 끝까지 안 나오면 런타임 에러 발생!!

그러므로 만약 nil이 나오면 file.endIndex를 넣어줬다~

여기에 떡하니.. 있다ㅋㅋㅋ (마지막 예제)

 

 

3. NUMBER가 5 이상이라면?

NUMBER는 1~5라고 했으므로 잘라줘야 한다. prefix를 사용해서 잘랐다!

 

 

func solution(_ files:[String]) -> [String] {
    return files.sorted { file1, file2 in
        let numberStartIndex1 = file1.firstIndex(where: { $0.isNumber })!
        let numberStartIndex2 = file2.firstIndex(where: { $0.isNumber })!
        let numberEndIndex1 = file1[numberStartIndex1...].firstIndex(where: { !$0.isNumber }) ?? file1.endIndex
        let numberEndIndex2 = file2[numberStartIndex2...].firstIndex(where: { !$0.isNumber }) ?? file2.endIndex
        let head1 = file1[file1.startIndex..<numberStartIndex1].lowercased()
        let number1 = file1[numberStartIndex1..<numberEndIndex1]
        let finalNumber1 = number1.count > 5 ? Int(number1.prefix(5))! : Int(number1)!
        let head2 = file2[file2.startIndex..<numberStartIndex2].lowercased()
        let number2 = file2[numberStartIndex2..<numberEndIndex2]
        let finalNumber2 = number2.count > 5 ? Int(number2.prefix(5))! : Int(number2)!
        
        if head1 == head2 {
            if finalNumber1 == finalNumber2 {
                return file1 == file2
            } else {
                return finalNumber1 < finalNumber2
            }
        }
        return head1 < head2
    }
}

먼가... 좀 더 줄이면 줄일 수 있을 것 같은 내 코드ㅎ

 

 


 

다른 사람의 코드를 보다 보니 정규식 표현으로 푼 사람들이 많았다.

정규식 표현 공부를 했었는데,, 생각이 잘 안 나네.. 다시 공부해야겠다

 

쉬운 문제인데 또 제한 조건을 제대로 안 봐서 시간이 좀 걸렸다ㅠㅠ

아놔~~ 정신 차리자... 다 적어놓고 시작해야겠다 😭

 

 

 

 

 

728x90