Java二进制搜索包含更多结果吗?

时间:2017-06-21 07:27:19

标签: java search autocomplete binary

我对二进制搜索有疑问。我有一个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如何得到以我的前缀开头的字符串的起始位置和结束位置?

2 个答案:

答案 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 匹配其他字符串的前缀)。这将为您提供起始和结束索引。