1+ #include < bits/stdc++.h>
2+
3+ using namespace std ;
4+
5+ // 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수
6+ int countByRange (vector<string>& v, string leftValue, string rightValue) {
7+ vector<string>::iterator rightIndex = upper_bound (v.begin (), v.end (), rightValue);
8+ vector<string>::iterator leftIndex = lower_bound (v.begin (), v.end (), leftValue);
9+ return rightIndex - leftIndex;
10+ }
11+
12+ // 문자열 내에서 특정한 문자열을 다른 문자열로 모두 치환하는 함수
13+ string replaceAll (string str, string from, string to){
14+ string res = str;
15+ int pos = 0 ;
16+ while ((pos = res.find (from, pos)) != string::npos)
17+ {
18+ res.replace (pos, from.size (), to);
19+ pos += to.size ();
20+ }
21+ return res;
22+ }
23+
24+ // 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트
25+ vector<string> arr[10001 ];
26+ // 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트
27+ vector<string> reversed_arr[10001 ];
28+
29+ vector<int > solution (vector<string> words, vector<string> queries) {
30+ vector<int > answer;
31+
32+ // 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입
33+ for (int i = 0 ; i < words.size (); i++) {
34+ string word = words[i];
35+ arr[word.size ()].push_back (word); // 단어를 삽입
36+ reverse (word.begin (), word.end ());
37+ reversed_arr[word.size ()].push_back (word); // 단어를 뒤집어서 삽입
38+ }
39+
40+ // 이진 탐색을 수행하기 위해 각 단어 리스트 정렬 수행
41+ for (int i = 0 ; i < 10001 ; i++) {
42+ sort (arr[i].begin (), arr[i].end ());
43+ sort (reversed_arr[i].begin (), reversed_arr[i].end ());
44+ }
45+
46+ // 쿼리를 하나씩 확인하며 처리
47+ for (int i = 0 ; i < queries.size (); i++) {
48+ string q = queries[i];
49+ int res = 0 ;
50+ if (q[0 ] != ' ?' ) { // 접미사에 와일드 카드가 붙은 경우
51+ res = countByRange (arr[q.size ()], replaceAll (q, " ?" , " a" ), replaceAll (q, " ?" , " z" ));
52+ }
53+ else { // 접두사에 와일드 카드가 붙은 경우
54+ reverse (q.begin (), q.end ());
55+ res = countByRange (reversed_arr[q.size ()], replaceAll (q, " ?" , " a" ), replaceAll (q, " ?" , " z" ));
56+ }
57+ // 검색된 단어의 개수를 저장
58+ answer.push_back (res);
59+ }
60+ return answer;
61+ }
0 commit comments