我正在将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;
}
答案 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)
查找时间。