https://programmers.co.kr/learn/courses/30/lessons/60060

 

코딩테스트 연습 - 가사 검색 | 프로그래머스

 

programmers.co.kr

 

트라이로 푼 문제

 

find를 비재귀로 했다가 효율성 3번만 계속 틀렸다

 

진짜 미쳐버리는줄 알았다 시간도 더빠르고 메모리도 동일한데 뭐가 문제란 말인지

 

정확성 테스트에서 예외 확인하고 효율성에서 시간 확인하는게 아닌건가??

 

맞왜틀

 

진자로 너무 화가낫다..

 

발상 자체는 금방 했는데 저 3번때문에 며칠을 꼬라박았다

 

답은 재귀였다.

 

아나

 

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
struct Trie
{
    Trie()
    {
        memset(next, 0sizeof(next));
        /*for (int i = 0; i < 26; ++i)
        {
            next[i] = nullptr;
        }*/
    }
    ~Trie()
    {
        for (int i = 0; i < 26++i)
        {
            if (next[i])
            {
                //std::cout << (char)('a' + i);
                delete next[i];
                //std::cout << '\n';
            }
        }
    }
 
    void insert(const char* word)
    {
        if (*word == '\0')
        {
            return;
        }
        ++size;
 
        int idx = *word - 'a';
        if (next[idx] == nullptr)
        {
            next[idx] = new Trie;
        }
        next[idx]->insert(word + 1);
    }
 
    unsigned int find_how_many(const char* word)
    {
        //엉뚱한 글자가 나오면 0을 리턴합니다
        if (next[word[0- 'a'== nullptr)
        {
            return 0;
        }
        // "?????"같은 상황을 대비해 첫글자가 '\0'이라면 해당 글자수의 모든 사이즈를 리턴합니다
        //if (*word == '\0')
        if (*word == '?')
        {
            return size;
        }
        
        //word를 따라가기 위한 idx 변수를 만듭니다.
        unsigned int idx = 0;
        //트라이의 링크를 따라가기 위한 tour변수를 만들었습니다.
        Trie* tour = next[word[idx++- 'a'];
        //'f????'같은 상황을 대비해 idx를 올리고 검사합니다.
        //if (word[idx] == '\0')
        if (word[idx] == '?')
        {
            return tour->size;
        }
 
        //word와 트라이 링크를 같이 따라갑니다
        while (tour->next[word[idx] - 'a'!= nullptr)
        {
            tour = tour->next[word[idx++- 'a'];
 
            //if (word[idx] == '\0')
            if (word[idx] == '?')
            {
                //word의 끝이 나오면 사이즈를 리턴합니다
                return tour->size;
            }
        } 
        return 0;
    }
 
    //unsigned int find_how_many(const char* word)
    //{
    //    if (*word == '?')
    //    {
    //        return size;
    //    }
    //    if (next[word[0] - 'a'] == nullptr)
    //    {
    //        return 0;
    //    }
 
    //    return next[word[0] - 'a']->find_how_many(word + 1);
    //}
 
public:
    Trie* next[26];
    unsigned int size = 0;
};
 
Trie trieArr[10001];
Trie rtrieArr[10001];
 
vector<int> solution(vector<string> words, vector<string> queries) {
    vector<int> answer(queries.size());
    //std::unordered_map<int, Trie> trieArr;
    //std::unordered_map<int, Trie> rtrieArr;
    //trieArr.reserve(10010);
    //rtrieArr.reserve(10010);
 
    std::string token;
    for (auto& it : words)
    {
        //입력받은 단어를 정방향으로 한번, 역방향으로 한번 넣었습니다.
        token.clear();
        token = it;
        std::reverse(token.begin(), token.end());
        rtrieArr[it.size()].insert(token.c_str());
        trieArr[it.size()].insert(it.c_str());
    }
 
    int idx = 0;
    for (auto& it : queries)
    {
        //첫글자가 ?이 아니면 정방향, ?이 나올때까지 쿼리의 단어를 token에 넣고 find를 돌렸습니다
        token.clear();
        if (it.front() != '?')
        {
 
            //int i = 0;
            //while (it[i] != '?')
            //{
            //    token += it[i++];
            //}
            //token += '\0';
            
            //answer[idx++] = trieArr[it.size()].find_how_many(token.c_str());
            
            answer[idx++= trieArr[it.size()].find_how_many(it.c_str());
        }
        else
        {
            //첫글자가 ?이면 역방향, 위와 마찬가지로 ?가 나올때까지 역방향으로 token에 넣고 find 함수에 넣었습니다
            
            std::reverse(it.begin(), it.end());
            //int i = it.size() - 1;
            //while (it[i] != '?')
            //{
            //    token += it[i--];
            //}
            //token += '\0';
 
            //answer[idx++] = rtrieArr[it.size()].find_how_many(token.c_str());
            
            answer[idx++= rtrieArr[it.size()].find_how_many(it.c_str());
        }
    }
    return answer;
}
 
int main()
{
    std::vector<std::string> words = { "frodo""front""frost""frozen""frame""kakao" };
    std::vector<std::string> queries = { "fro??""????t""fr???""fro???""pro?" };
    for (auto it : solution(words, queries))
    {
        std::cout << it << ' ';
    }
    return 0;
}
cs

문제의 틀린 답. 주석처리 된 find_how_many 재귀함수를 사용하면 정답이다.

+ Recent posts