我对二进制搜索有疑问。我有一个arraylist,我使用它来搜索列表中带有前缀的字符串:
if(prefix.length()>1){
prefixlow=prefix.toLowerCase();
int n = Collections.binarySearch(words, prefixlow);
if (n < 0 && -n <= words.size()) {
String match = words.get(-n - 1);
if (match.startsWith(prefixlow)) {
// A completion is found
completion = match.substring(0+prefix.length());
keyboardwindow.jTextArea1.setText(prefix+completion);
}
}
else{keyboardwindow.jTextArea1.setText(prefix);}
}
现在这只是找到一个结果。下一步是从列表中获取所有该词,而不仅仅是一个。所以第一个问题是,这总是找到以前缀开头的第一个单词吗?因为我认为它只是以前缀开头给你一个随机字符串...所以任何tipps如何得到以我的前缀开头的字符串的起始位置和结束位置?
答案 0 :(得分:0)
List<String>
上的二进制搜索将找到您要查找的前缀的确切出现的索引。如果您的前缀在List
中多次出现(不是作为较长String
的前缀,而是作为整个String
),您将获得其中一个出现的索引(不一定是第一个。)
但是,看起来您不希望您要查找的前缀出现在List
中(作为整个String
),这就是为什么您期望负指数为返回。
在这种情况下,binarySearch()
将根据元素的自然顺序返回您的前缀在List
中出现的索引的负值。
由于字符串的自然顺序是字典顺序,因此前缀将在以该前缀开头的任何更长的String
之前出现。因此,您可以简单地从List
开始迭代-n - 1
并从您的前缀开始获取所有String
。
例如:
List<String> binSearch = Arrays.asList ("aaa","aab","aac","bba","bbb","bbbb","c");
System.out.println ("-n-1 = " + (-Collections.binarySearch (binSearch, "bb")-1));
打印:
-n-1 = 3
3是前缀“bb”的索引(如果它出现在List
中),但由于它不在列表中,你知道所有{{1}以“bb”开头的s位于索引&gt; = 3。
因此,可以通过将String
条件替换为循环来修改代码:
if (match.startsWith(prefixlow))
答案 1 :(得分:0)
你在这里是正确的,你会得到一个带有搜索前缀的随机字符串。但是数组是排序的,因此您可以从找到的索引在两个方向上执行交互,而( yourPrefix 匹配其他字符串的前缀)。这将为您提供起始和结束索引。