我正在制作一个移动应用程序,需要进行数千次快速字符串查找和前缀检查。为了提高速度,我使用我的单词列表构建了Trie,其中约有180,000个单词。
一切都很好,但唯一的问题是,在我的手机上构建这个庞大的Trie(它有大约400,000个节点)目前需要大约10秒,这真的很慢。
这是构建Trie的代码。
public SimpleTrie makeTrie(String file) throws Exception {
String line;
SimpleTrie trie = new SimpleTrie();
BufferedReader br = new BufferedReader(new FileReader(file));
while( (line = br.readLine()) != null) {
trie.insert(line);
}
br.close();
return trie;
}
insert
方法的时间复杂度为 O(键的长度)
public void insert(String key) {
TrieNode crawler = root;
for(int level=0 ; level < key.length() ; level++) {
int index = key.charAt(level) - 'A';
if(crawler.children[index] == null) {
crawler.children[index] = getNode();
}
crawler = crawler.children[index];
}
crawler.valid = true;
}
我正在寻找构建Trie树的直观方法来提高构建速度。也许我可以在笔记本电脑上仅构建一次Trie树,以某种方式将其存储到磁盘中,然后从文件中加载它到手机中?但我不知道如何实现这个功能。
或者是否有其他前缀数据结构可以更快地构建,但具有类似的查找时间复杂度?
任何建议都将不胜感激。先感谢您。
编辑
有人建议使用Java序列化。我尝试了一下,但是以下代码非常慢:
public void serializeTrie(SimpleTrie trie, String file) {
try {
ObjectOutput out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
out.writeObject(trie);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public SimpleTrie deserializeTrie(String file) {
try {
ObjectInput in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
SimpleTrie trie = (SimpleTrie)in.readObject();
in.close();
return trie;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
以上的代码能否做得更快?
我的Trie实现:http://pastebin.com/QkFisi09
单词列表:http://www.isc.ro/lists/twl06.zip
用于运行代码的Android IDE:http://play.google.com/store/apps/details?id=com.jimmychen.app.sand
性能比较 DAFSA内存消耗:16020976 DAFSA(毫秒):[100] 0 DAFSA(毫秒):[10000] 5 DAFSA(毫秒):[1000000] 28
trie内存消耗:12946984 trie(毫秒):[100] 0 trie(毫秒):[10000] 6 trie(毫秒):[1000000] 131
List内存消耗:1761728 List(毫秒):[100] 23 List(毫秒):[10000] 696 List(毫秒):[1000000] 71752
Set内存消耗:2341616 Set(毫秒):[100] 0 Set(毫秒):[10000] 1 Set(毫秒):[1000000] 22 - Amit Kumar Gupta