我目前正在使用大量字符串(+2000)的java应用程序中工作。我想将这些字符串存储在一个合适的结构中,所以当我想存储一个新的字符串时,我可以快速检查是否已存在相同的字符串。如果结构中没有相同的字符串,我继续存储新的(基本上存储而不重复字符串。)。
//PSEUDOCODE
private ?????? myCollectionOfStrings;
public void store_If_Not_Exist(String aNewString){
if (!exist_in_Collection(aNewString)){ //this must be fast.
store_in_Collection(aNewString);
}
}
我目前正在使用一个天真的实现,但我知道这是非常低效的:
private List<String> myCollectionOfStrings;
public void store_If_Not_Exist(String aNewString){
boolean existInCollection = false;
for (String s: myCollectionOfStrings){
if (s.equals(aNewString)){
existInCollection = true;
break;
}
}
if(!existInCollection)
store_in_Collection(aNewString);
}
问题是:我可以使用什么样的方法/结构/算法来存储字符串,因此可以快速实现对存在的检查?也许是Trie Tree或HashMap ???谢谢!
答案 0 :(得分:2)
如果按字母顺序维护单词并不重要,那么只需使用HashSet即可。它允许您检索O(1)中的任何元素,您只需将该单词添加到集合中,而无需担心创建重复项。
哈希集合的唯一问题是迭代它们时不保持自然顺序。换句话说,HashSet不会按字母顺序打印您的单词。
如果订单对您的应用程序至关重要,我的建议是您使用TreeMap或Trie。它们都具有一些特征和基本结构,但Trie针对字符串进行了优化。
如果您不想过度复杂化,请使用属于集合框架的TreeMap。
但是如果你想在效率的道路上走得更远,那么你正在寻找的数据结构是一个特里。
https://en.wikipedia.org/wiki/Trie
总之,Trie是一种数据结构,允许您按字母顺序存储字符串。它功能非常强大,因为它可以让您快速检测到单词丢失。
想象一下,你想要检查单词“foo”的存在,如果它不在你的树中,你想要添加它。
正如您在维基百科文章中所看到的,Trie的根节点包含一个空字符串。您确定单词foo是否在Trie中的第一个操作是检查根节点是否有一个字符串为“f”的子节点。如果没有,你已经知道这个词不在你的Trie中,你只做了一个操作。
另一方面,如果根节点有一个字符串为“f”的子节点,那么你必须检查这个节点是否有一个字符串为“fo”的子节点,如果没有,你的话就是不是在特里。如果是,则最后检查“fo”节点是否有名为“foo”的子节点。
总而言之,Trie正是您所寻找的,它将允许您在保持其自然顺序的同时有效地插入和检查单词的存在。
在这篇论坛帖子中,你可以看到一个trie的实现,所以你不必重新发明轮子。
https://community.oracle.com/thread/2070706
总结: