我的二进制搜索算法有问题吗?

时间:2015-08-03 16:08:46

标签: java arraylist binary-search

我正在编写一个程序,您可以在其中输入将存储在ArrayList中的单词。然后,您可以通过在textField中输入并按下按钮来搜索这些单词。 (如果按另一个按钮,您也可以对它们进行排序)。如果找到该单词,则应该打印出该单词的ArrayList中的位置,如果找不到该单词应该打印出来。我认为直到最近我测试它时它才起作用(它之前已经有效):我输入了一个我知道在ArrayList中的单词,它使得它打印出ArrayList中单词的位置(这就是我想要它做的) )。然后我输入了一个我知道在ArrayList中不存在的单词,该单词打印出该单词不存在(这也是我想要它做的)。但是当我在那之后搜索了一个我知道存在于ArrayList中的单词时,它打印出无法找到该单词。然后我用另一个我在ArrayList中存在的单词尝试了这个,但我也找不到。我有几次重新启动程序,有时它工作,有时它没有,我不知道为什么或为什么不...

在运行算法之前对数组进行排序,因此我知道这不是问题...

下面是我的搜索算法的类:

public class SearchAlg {

  public static String binary (ArrayList<String> list, String user) {
    int first = 0;
    int found = 0;
    int middle = 0;
    int last = list.size();
    String strFound = "";

    while (first < last && found == 0) {
        middle = ((first + last) / 2);
        if (user.compareTo(list.get(middle)) > 0) {
            first = middle + 1;
        } else if (user.compareTo(list.get(middle)) == 0) {
            found = 1;
        } else if (user.compareTo(list.get(middle)) < 0) {
            last = middle - 1;
        }
    }
    if (found == 1) {
        strFound = "The word " + user + " exists on the place " + middle + " in the Arraylist";
    } else {
        strFound = "The word " + user + " does not exist in the Arraylist";
    }
    return strFound;
  }
}

这是我的排序算法:     public class Sort {         static private String strTemp;         static private int i;         static private int n;

public static ArrayList bubbelSort (ArrayList<String> list) {
    for (i = 0; i < list.size(); i++) {
        for (n = 0; n < list.size() - i - 1; n++) {
        if (list.get(n).compareTo(list.get(n + 1)) > 0) {
            strTemp = list.get(n);
            list.set(n, list.get(n + 1));
            list.set(n + 1, strTemp);
        }
    }
    }
    return list;
}

这是我的Main课程:

ArrayList<String> list = new ArrayList();

private void btnEnterActionPerformed(java.awt.event.ActionEvent evt) {                                          
    txtaOutput.setText("");
    String wrd = txtfEnter.getText();
    list.add(wrd);
    for (int i = 0; i < list.size(); i++) {
        txtaOutput.append(list.get(i) + "\n");
    }
}

private void btnSortActionPerformed(java.awt.event.ActionEvent evt) {                                            
    txtaOutput.setText("");
    Sort.bubbelSort(list);
}

private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {                                        
    // TODO add your handling code here:
    String user = txtfSearch.getText();
    txtaOutput.setText("");
    String bin = SearchAlg.binary(list, user);
    txtaOutput.append(bin);
}

我不知道造成这种情况的原因,所以对任何帮助表示赞赏!

编辑:我现在知道问题是ArrayList中的第一项无法搜索。因此,如果ArrayList包含a, b, c,那么只有bc可供搜索。如果我尝试搜索a,则表示无法找到它。

3 个答案:

答案 0 :(得分:1)

    int first= 0;
    int last= a.length - 1;
    while (first<= last) {
        int middle = first+ (last- first) / 2;
        if      (user.compareTo(list.get(middle)) < 0) last = middle - 1;
        else if (user.compareTo(list.get(middle)) > 0) first= middle + 1;
        else {
        found =1 ;
        break;
        }
    }

并且不要忘记按照上一篇文章中提到的列表进行排序

答案 1 :(得分:0)

问题出在搜索的最后一步。你有可能更新'first'和'last',在下一次迭代中你会找到值,但是你会从循环中断开。

解决方案:完全删除变量found,以及这两行:

} else if (user.compareTo(list.get(middle)) == 0) {
        found = 1;

你现在写的地方......

if (found == 1) {    

......反而......

if (user.compareTo(list.get(first)) == 0) {

答案 2 :(得分:0)

你是一个人。

您使用last = list.size()初始化该方法,这意味着您正在搜索半开的时间间隔[first, last>(包括first,但不包括last)。< / p>

但是,在您的循环中,您设置了last = middle - 1,如果您的搜索范围是关闭的时间间隔[first, last](包括first,包括last,则可以使用last })。

您应该决定while (first < last && found == 0) { middle = ((first + last) / 2); if (user.compareTo(list.get(middle)) > 0) { first = middle + 1; } else if (user.compareTo(list.get(middle)) == 0) { found = 1; } else if (user.compareTo(list.get(middle)) < 0) { last = middle; // <-- Remove -1 } } 是否应该指向最后一个元素,或指向最后一个元素。如果你选择后者,这就是你的循环:

d = ["2015-08-03T09:00:00-07:00","2015-08-03T10:00:00-07:00","2015-08-03T11:00:00-07:00","2015-08-03T12:00:00-07:00",
     "2015-08-03T13:00:00-07:00","2015-08-03T14:00:00-07:00"]

from dateutil import parser

for dte in d:
    print(parser.parse(dte))