Skip to content

Commit ae12971

Browse files
add: 문자사전
1 parent 51256af commit ae12971

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
7+
// NOTE: dot에 대한 wildcard 검색이 핵심이었던 문제.
8+
// NOTE: tc -> 문자 입력 O(n), 패턴검색 O(26^n), 패턴X검색 O(1)
9+
10+
/**
11+
검색어 | 의미
12+
"." | 길이가 1인 아무 문자와 매치
13+
".a" | 길이 2: 첫 글자는 아무 문자, 두 번째는 a
14+
"..d" | 길이 3: 처음 두 글자는 아무 문자, 마지막은 d
15+
"..." | 길이 3인 모든 단어와 매치
16+
*/
17+
class WordDictionary {
18+
19+
private WordDictionary[] child;
20+
private Character val;
21+
private Map<String, Boolean> cMap;
22+
23+
public WordDictionary() {
24+
this.cMap = new HashMap<>();
25+
this.val = null;
26+
}
27+
28+
public void addWord(String word) {
29+
if(this.cMap.containsKey(word)) return;
30+
31+
this.cMap.put(word, true);
32+
this.innerInsert(word);
33+
}
34+
35+
public void innerInsert(String word) {
36+
if(word.length() == 0) return;
37+
38+
if(this.child == null) {
39+
this.child = new WordDictionary[26];
40+
}
41+
42+
char c = word.charAt(0);
43+
int idx = c - 97;
44+
45+
if(this.child[idx] == null) {
46+
this.child[idx] = new WordDictionary();
47+
this.child[idx].val = c;
48+
}
49+
50+
this.child[idx].innerInsert(word.substring(1));
51+
}
52+
53+
public boolean search(String word) {
54+
if(!word.contains(".")) return this.cMap.containsKey(word);
55+
56+
57+
return this.patternSearch(word);
58+
}
59+
60+
private boolean patternSearch(String wildcard) {
61+
if(wildcard.length() == 0) return true;
62+
63+
char c = wildcard.charAt(0);
64+
if(c == '.') { // NOTE: wildcard를 만났을 때, 해당 depth는 검사하지 않고, 다음 번(자식) 문자들에 대해서 검색 이어나가기.
65+
List<Boolean> res = new ArrayList<>();
66+
67+
for(WordDictionary children : this.child) {
68+
if(children != null) {
69+
res.add(children.patternSearch(wildcard.substring(1)));
70+
}
71+
}
72+
73+
for(boolean b : res) {
74+
if(b) return true;
75+
}
76+
77+
return false;
78+
}
79+
80+
int idx = c - 97;
81+
if(this.child == null || this.child[idx] == null || this.child[idx].val == null) return false;
82+
83+
return this.child[idx].patternSearch(wildcard.substring(1));
84+
}
85+
}
86+
87+
/**
88+
* Your WordDictionary object will be instantiated and called as such:
89+
* WordDictionary obj = new WordDictionary();
90+
* obj.addWord(word);
91+
* boolean param_2 = obj.search(word);
92+
*/
93+
94+
95+
// 이전 TRIE 자료구조를 모른 채로 풀이했던 문제..
96+
class PrevWordDictionary {
97+
98+
private String word;
99+
private PrevWordDictionary leftChild;
100+
private PrevWordDictionary rightChild;
101+
102+
public PrevWordDictionary() {
103+
this.leftChild = null;
104+
this.rightChild = null;
105+
this.word = null;
106+
}
107+
108+
public void addWord(String word) {
109+
if(this.word == null) {
110+
this.word = word;
111+
return;
112+
}
113+
114+
// NOTE: 사전 순으로 크고 작음을 두어 이진처리.
115+
if(this.word.compareTo(word) == 1) {
116+
117+
this.rightChild = new PrevWordDictionary();
118+
this.rightChild.addWord(word);
119+
} else if (this.word.compareTo(word) == -1) {
120+
121+
this.leftChild = new PrevWordDictionary();
122+
this.leftChild.addWord(word);
123+
} else {
124+
// already exists. just return
125+
}
126+
}
127+
128+
public boolean search(String word) {
129+
if(word.contains(".")) {
130+
// String replaced = word.replace(".", "");
131+
132+
// return word.startsWith(".") ? this.startsWith(replaced) : this.endsWith(replaced);
133+
return this.patternSearch(word.replace(".", ""));
134+
}
135+
136+
if(this.word == null) {
137+
return false;
138+
}
139+
140+
if(this.word.equals(word)) {
141+
return true;
142+
}
143+
144+
if(this.rightChild == null && this.leftChild == null) {
145+
return false;
146+
}
147+
148+
if(this.word.compareTo(word) == 1) {
149+
return this.rightChild == null ? false : this.rightChild.search(word);
150+
} else {
151+
return this.leftChild == null ? false : this.leftChild.search(word);
152+
}
153+
}
154+
155+
private boolean patternSearch(String wildcard) {
156+
if(this.word.contains(wildcard)) return true;
157+
158+
boolean left = false;
159+
boolean right = false;
160+
if(this.leftChild != null) {
161+
left = this.leftChild.patternSearch(wildcard);
162+
}
163+
164+
if(this.rightChild != null) {
165+
right = this.rightChild.patternSearch(wildcard);
166+
}
167+
168+
return left || right;
169+
}
170+
}

0 commit comments

Comments
 (0)