-
Notifications
You must be signed in to change notification settings - Fork 7
/
CharTree.java
186 lines (160 loc) · 4.8 KB
/
CharTree.java
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
178
179
180
181
182
183
184
185
186
package test_jcseg;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class Test {
private static final CharNode NOT_CONTAIN_NODE = new CharNode(' ', null);
private static final CharNode CONTAIN_BUT_NOT_WORD_NODE = new CharNode(' ',
null);
public static void main(String[] args) {
CharTree charTree = new CharTree();
charTree.appendWord("abc");
charTree.appendWord("abd");
System.out.println(charTree.containWord("bcd"));
System.out.println(charTree.containWord("abc"));
System.out.println(charTree.containWord("abd"));
System.out.println(charTree.containWord("ab"));
for (String str : charTree.listContainWords("feoejfoabcjfelfjlabd")) {
System.out.println(str);
}
}
public static class CharTree {
public CharNode root = new CharNode(' ', null);
public CharTree() {
}
public List<String> listContainWords(String str) {
List<String> wordList = new ArrayList<String>();
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length; i++) {
for (int j = i + 1; j <= charArray.length; j++) {
String substring = str.substring(i, j);
ContainResult containResult = this.containWord(substring);
if (containResult.equals(ContainResult.NOT_CONTAIN)) {
break;
}
if (containResult.equals(ContainResult.CONTAIN)) {
wordList.add(substring);
}
}
}
return wordList;
}
public void appendWord(String word) {
CharNode currentCharNode = root;
char[] charArray = word.toCharArray();
for (int i = 0; i < charArray.length; i++) {
boolean isWord = false;
char c = charArray[i];
if (i == charArray.length - 1) {
isWord = true;
}
currentCharNode = appendCharNode(currentCharNode, c, isWord);
}
}
private CharNode appendCharNode(CharNode currentCharNode, char c,
boolean isWord) {
CharNode[] charNodes = currentCharNode.getCharNodes();
if (charNodes == null) {
charNodes = new CharNode[0];
currentCharNode.setCharNodes(charNodes);
}
CharNode childCharNode = new CharNode(c, null);
int index = Arrays.binarySearch(charNodes, childCharNode);
if (index < 0) {
CharNode[] newCharNodes = Arrays.copyOf(charNodes,
charNodes.length + 1);
newCharNodes[newCharNodes.length - 1] = childCharNode;
Arrays.sort(newCharNodes, new Comparator<CharNode>() {
@Override
public int compare(CharNode o1, CharNode o2) {
if (o1.getC() == o2.getC()) {
return 0;
}
return o1.getC() > o2.getC() ? 1 : -1;
}
});
charNodes = newCharNodes;
currentCharNode.setCharNodes(charNodes);
System.out.println(childCharNode.getC());
index = Arrays.binarySearch(charNodes, childCharNode);
}
currentCharNode.getCharNodes()[index].setWord(isWord);
return currentCharNode.getCharNodes()[index];
}
public ContainResult containWord(String word) {
CharNode currentCharNode = root;
char[] charArray = word.toCharArray();
for (int i = 0; i < charArray.length; i++) {
boolean isWord = false;
char c = charArray[i];
if (i == charArray.length - 1) {
isWord = true;
}
currentCharNode = containCharNode(currentCharNode, c, isWord);
if (currentCharNode == NOT_CONTAIN_NODE) {
return ContainResult.NOT_CONTAIN;
} else if (currentCharNode == CONTAIN_BUT_NOT_WORD_NODE) {
return ContainResult.CONTAIN_BUT_NOT_WORD;
}
}
return ContainResult.CONTAIN;
}
private CharNode containCharNode(CharNode currentCharNode, char c,
boolean isWord) {
CharNode[] charNodes = currentCharNode.getCharNodes();
CharNode childCharNode = new CharNode(c, null);
if (charNodes == null || charNodes.length == 0) {
return NOT_CONTAIN_NODE;
}
int index = Arrays.binarySearch(charNodes, childCharNode);
if (index >= 0) {
if (isWord) {
if (charNodes[index].isWord) {
return charNodes[index];
}
return CONTAIN_BUT_NOT_WORD_NODE;
}
return charNodes[index];
}
return NOT_CONTAIN_NODE;
}
}
public static enum ContainResult {
CONTAIN, NOT_CONTAIN, CONTAIN_BUT_NOT_WORD,
}
public static class CharNode implements Comparable<CharNode> {
private char c;
private CharNode[] charNodes;
private boolean isWord = false;
public CharNode(char c, CharNode[] charNodes) {
this.c = c;
this.charNodes = charNodes;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public CharNode[] getCharNodes() {
return charNodes;
}
public void setCharNodes(CharNode[] charNodes) {
this.charNodes = charNodes;
}
public boolean isWord() {
return isWord;
}
public void setWord(boolean isWord) {
this.isWord = isWord;
}
@Override
public int compareTo(CharNode o) {
if (this.getC() == o.getC()) {
return 0;
}
return this.getC() > o.getC() ? 1 : -1;
}
}
}