从HashSet(或其他集合)中过滤掉字符串

时间:2015-09-30 12:55:36

标签: java string

我正在将txt文件的内容读入HashSet。该文件几乎包含英语中的每个单词,每个单词都成为HashSet中的字符串。

在我的应用中,字符被添加到字符串中。我想检查这个String是否是HashSet中的任何字符串,或者可以变得相等。也就是说,HashSet只包含String apple 。我有一个String appl ,现在我想过滤掉HashSet,直到它变成一个只有以 appl 开头的字符串的集合(在这种情况下是只设置 apple )。

我可以遍历整个HashSet并使用startsWith(String)方法,因为我构建了一个新的过滤的HashSet。但是我的初始HashSet非常大,所以我的问题是:是否有更有效的方法(可能使用不同类型的集合?)

我现在该怎么做的一些代码:

private HashSet<String> filter(String partOfWord){
    HashSet<String> filteredSet = new HashSet<>();

    for (String word : dictionary) { // dictionary is the full HashSet
        if (word.startsWith(partOfWord)) {
            filteredSet.add(word);
        }
    }
    return filteredSet;
}

1 个答案:

答案 0 :(得分:3)

trie是此任务的终极武器,但你可以从TreeSet中获得良好的效率:

private TreeSet<String> dictionary;

private TreeSet<String> filter(String partOfWord) {
    return (TreeSet<String>)dictionary.subSet(partOfWord, partOfWord + "zzz");
}

以“appl”开头的所有内容也是“appl”之间的(包括它是一个单词本身)和“applzzz”(没有英文单词中有3个连续的“z”) ,字典上比以“appl”开头的所有单词都要大。调用subset()的时间复杂度为O(log n)以查找子集的开头,并为该范围找到O(m)(m =返回的数字),这非常好。

请注意,如果您在单词增长时能够将返回的集重用为新字典,那么整体代码将更加高效。

需要转化为TreeSet<String>,因为subSet()SortedSet界面的一种方法并返回SortedSet,但它是covariant因为TreeSet implementation 3}}返回视图(另一种效率优势),当然是另一种TreeSet

为了提高效率,但是更丑陋的代码,你可以使用排序String[]Arrays.binarySearch(),然后一旦找到你的命中,你就可以快速迭代你的命中数组。

请注意,TreeSet和已排序的数组都有O(log n)查找时间,而HashSet(虽然不适合该任务)是O(1)查找时间。