高效的方式/结构只能存储不同的字符串

时间:2016-04-22 16:43:58

标签: java string structure

我目前正在使用大量字符串(+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 ???谢谢!

1 个答案:

答案 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

总结:

  • 我不关心维护特定的顺序:使用HashSet
  • 我关心按字母顺序维护单词,我想要一个简单的解决方案,即使它不是最有效的:使用TreeMap
  • 我需要按字母顺序排列,性能至关重要:使用Trie。