프로그래머스의 파일명 정렬(Lv2) 문제이다.


[ 문제풀이 ]

문제를 크게 3가지 과정으로 나눠서 진행해보자.


#1. 조건에 맞는 형식으로 파일명 Remake

먼저, 첫번째로 파일명에서 Head부분에서는 "대소문 구분을 하지 않는다" 라고 되어있다.

따라서, 본인은 파일명에서 Head부분에 있는 문자들 중에서, 대문자인 문자들을 모두 대문자로 변경해 주었다.

즉, 모든 문자들을 대문자로 통일 시켜주었다.


두번째로, Number 부분에서는 숫자 앞에 '0'이 붙은 형태로 존재할 수 있다고 되어있다.

즉, 012와 12는 같은 숫자로 처리되므로, 정렬을 시키더라도 이 2개의 순서는 달라질 수가 없게 된다.

그래서, Number부분을 모두 앞에 있는 '0'을 제외한 정상적인 숫자의 형태로만 존재하도록 만들어 주었다.


#2. 파일명을 정렬할 수 있도록 새로운 저장공간에 옮기기

우리는 주어진 문자열을, Head, Number, Tail부분으로 나눠서 판단했을 때, 문제에서 제시한 조건대로 정렬을 시켜주어야 한다.

따라서, 본인은 { Head , Number , Tail , Idx } 를 멤버변수로 가지는 구조체를 하나 만들어주었다.

Head, Number, Tail은 string형 멤버변수로써, 파일명을 Head와 Number, Tail로 구분했을 때, 각각에 속하는 부분을 저장해 놓기 위한 멤버변수이고, Idx는 "원본 파일명에서 존재했던 Idx번호를 저장하기 위한 멤버변수" 인데, 이 부분에 대해서는 #3에서 다시한번 설명하겠다.

위의 구조체를 자료형으로 하는 vector를 하나 만들어서, 주어진 파일들을 모두 Head, Number, Tail, Idx로 나눠서 vector에 삽입해 주었다.


#3. 정답 도출하기

최종적으로는 #1에서 Remake한 파일명들을 #2에서 Head부분, Number부분, Tail부분으로 나눠서 따로 저장해 주었으므로, 이를 조건에 맞게 정렬만 시켜주면 된다.

Head순으로 가장 우선적으로 정렬을 시켜주고, 2차적으로 Number부분을 기준으로 사전순으로 정렬을 시켜주면 된다.

그리고 정렬 후 출력을 시켜 주면 되는데, 이 때, #2에서 저장한 벡터를 출력을 시켜주면 안된다.

왜냐하면, 우리는 원본의 데이터를 #1에서 Remake하고, 이 Remake한 데이터들을 새롭게 저장해놓은 상태이기 때문에, 원본의 데이터와는 상태가 많이 다를 수 있다.

예를 들어서 원본의 데이터가 "MuZi01.txt" 였다면, 우리가 관리하고 있는 데이터는 "muzi1.txt" 일 것이다.

즉, 우리가 출력해야 하는 데이터는 "MuZi01.txt"가 되야 한다는 것이다.

따라서, 본인은 이 모든 과정을 하기에 앞서, 원본 데이터를 따로 저장해 주었다.

그리고, #2에서 선언한 구조체에서 'Idx'라는 변수가 있다고 했었는데, 이 Idx라는 멤버변수가 이 과정에서 필요하다.

#2에서 구조체 Vector를 정렬시키고 나면, 1차적으로 Head부분이 사전순으로 가장 빠른 파일이, 2차적으로 Number부분이 사전순으로 가장 빠른 파일이 앞쪽에 배치될 것이다.

이 때, 실제로 출력해야 하는 것은, 이 파일들이 가지고 있는 Idx번호를 통해서, 원본 데이터의 Idx번 파일명을 출력해야 한다는 것이다.


[ 소스코드 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <string>
#include <vector>
#include <algorithm>
 
using namespace std;
 
struct MY_FILE
{
    string Head;
    string Number;
    string Tail;
    int Idx;
};
 
void Remake_Word(vector<string> &File)
{
    for (int i = 0; i < File.size(); i++)
    {
        string Result = "";
        for (int j = 0; j < File[i].length(); j++)
        {
            char C = File[i][j];
            if (('a' <= C && C <= 'z'|| ('A' <= C && C <= 'Z'))
            {
                C = toupper(C);
                Result += C;
            }
            else if ('0' <= C && C <= '9')
            {
                string Num = "";
                while ('0' <= File[i][j] && File[i][j] <= '9')
                {
                    Num += File[i][j++];
                }
                j--;
                int To_Int = stoi(Num);
                Num = to_string(To_Int);
                Result += Num;
            }
            //else if (C == ' ') continue;
            else Result += File[i][j];
        }
        File[i] = Result;
    }
}
 
void Make_FileList(vector<string> File, vector<MY_FILE> &List)
{
    for (int i = 0; i < File.size(); i++)
    {
        string Head_Part = "";
        string Num_Part = "";
        string Tail_Part = "";
 
        int Num_Start;
        int Num_End;
 
        for (int j = 0; j < File[i].length(); j++)
        {
            if ('0' <= File[i][j] && File[i][j] <= '9')
            {
                Num_Start = j;
                while ('0' <= File[i][j] && File[i][j] <= '9')
                {
                    Num_Part += File[i][j];
                    j++;
                }
                Num_End = j;
                break;
            }
        }
 
        for (int j = 0; j < Num_Start; j++) Head_Part += File[i][j];
        for (int j = Num_End; j < File[i].length(); j++) Tail_Part += File[i][j];
        
        List.push_back({ Head_Part, Num_Part, Tail_Part , i});
    }
}
 
bool Cmp(MY_FILE A, MY_FILE B)
{
    if (A.Head <= B.Head)
    {
        if (A.Head == B.Head)
        {
            int A_Num = stoi(A.Number);
            int B_Num = stoi(B.Number);
            if (A_Num <= B_Num)
            {
                if (A_Num == B_Num)
                {
                    if (A.Idx < B.Idx)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
            return false;
        }
        return true;
    }
    return false;
}
 
vector<string> solution(vector<string> files) 
{
    vector<string> Original = files;
    vector<string> answer;
    vector<MY_FILE> List;
    Remake_Word(files);
    Make_FileList(files, List);
    sort(List.begin(), List.end(), Cmp);
    for (int i = 0; i < List.size(); i++)
    {
        int Idx = List[i].Idx;
        answer.push_back(Original[Idx]);
    }
    return answer;
}
cs




+ Recent posts