알고리즘

프로그래머스 - 파일명 정리

SniKuz 2024. 5. 28. 17:44

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

 

프로그래머스

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

programmers.co.kr


문제 설명

파일명이 담긴 배열 files를 아래 조건을 토대로 정렬시켜주십시오.

1. 파일명을 HEAD, NUMBER, TAIL 3 부분으로 나눕니다.
HEAD는 첫 파일명부터 숫자가 아닌 부분까지의 문자열입니다. 최소 1글자 이상입니다.
NUMBER는 HEAD 이후부터 연속된 숫자로 이루어진 부분입니다. 최소 1글자, 최대 5글자 이내입니다.
TAIL은 HEAD와 NUMBER을 제외한 나머지 부분으로, 숫자, 글자가 있을 수 있으며 아무 글자도 없을 수 있습니다.

2. HEAD 기준으로 사전순으로 정렬합니다. 이 때 문자열 비교 시 대소문자 구분을 하지 않습니다. MUZI, muzi. MuZi는 정렬 시 같은 순서로 취급됩니다.

3. HEAD가 대소문자 차이 외에는 같을 경우 숫자 순으로 정렬합니다. 이 때 숫자 앞의 0은 무시됩니다.
예를들어 9 < 10 < 0011 < 012 < 13 순으로 정렬됩니다.

4. HEAD, NUMBER가 모두 같을 경우 원래 입력에 주어진 순서를 유지합니다. Kim01.png, kIm01.jpg가 들어왔다면 정렬 후에도 주어진 두 파일의 순서가 바뀌면 안됩니다.


아이디어

● 문자열 앞부터 숫자가 나올 때 까지 확인해 HEAD를 분리하고, 숫자가 나오지 않을 때 까지 확인해 NUMBER를 분리합니다.

● HEAD는 문자열 비교 시 대소문자 구분을 하지 않기 때문에, 소문자로 통일 시킵니다.

● HEAD가 동일하다면 NUMBER를 비교합니다.

● 주어진 순서를 유지해야하기 때문에 stable_sort를 사용합니다.


코드

#include <bits/stdc++.h>

using namespace std;

unordered_set<char> numbers = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

vector<string> Split(const string& str) {
    vector<string> ret(2);
    int i = 0;
    while (i < str.size() && numbers.find(str[i]) == numbers.end()) {
        ret[0] += tolower(str[i]);
        ++i;
    }

    int number_start = i;
    while (i < str.size() && numbers.find(str[i]) != numbers.end()) {
        ++i;
    }

    ret[1] = str.substr(number_start, i - number_start);
    return ret;
}


vector<string> solution(vector<string> files) {
    stable_sort(files.begin(), files.end(), [] (const string& a, const string& b)
    {
        auto splitA = Split(a);
        auto splitB = Split(b);

        if (splitA[0] < splitB[0]) return true;
        if (splitA[0] > splitB[0]) return false;

        return stoi(splitA[1]) < stoi(splitB[1]);
    });
    return files;
}

substr(pos, length)인점 , HEAD가 동일할 때만 NUMBER 비교 주의하기...