【问题标题】:Binary Search - Error二进制搜索 - 错误
【发布时间】:2013-06-16 08:42:51
【问题描述】:

我有一份学生名单,我想按姓氏对他们进行排序。 学生名单看起来有点像这样:

Amanda
Dorris
Tucker
Yasmin
Zara

我想用二分法搜索这些学生,输出想要的结果。

这是我目前所拥有的:

public void binarySearch(String keyword) {

    int output;

    if (fileSorted == false) {
        System.out.println("The file " + fileName + " is not sorted. Please wait while it gets sorted...");
        bubbleSort();
        System.out.println("Thank you for your patience.");
        System.out.println();
        System.out.print("Search for: ");
        keyword = elmo.nextLine();
        output = doBinarySearch(keyword);
    } else {
        output = doBinarySearch(keyword);
    }
    System.out.println(output);
}

public int doBinarySearch(String keyword) {

    int start = 0;
    int end = numStudents - 1;
    int mid;
    int result;

    while (start < end) {
        mid = start + (end - start) / 2;
        result = students[mid].returnLastName().compareToIgnoreCase(keyword);

        if (result == 0) {
            return mid;
        } else if ((end - start) <= 1 ) {
            return -1;
        } else if (result > 0) {
            start = mid;
        } else if (result < 0) {
            end = mid;
        }
    }
    return -1;
}

【问题讨论】:

  • 会发生什么不符合您的预期?换句话说,具体是什么问题?
  • System.out.println(输出);不给我输出。程序死了:(
  • “程序死了”是什么意思?通常,您会收到包含有价值信息的异常消息。请张贴。
  • 有错误的堆栈跟踪会很有用
  • 输入关键字后,程序没有回复...

标签: java binary binary-tree binary-search-tree binary-search


【解决方案1】:

线

mid = ((end - start) / 2);

错了。您需要将mid 设置为(大致)startend 的中点,所以

mid = start + (end - start) / 2;

mid = (end + start) / 2;

如果你不怕溢出。

根据您所拥有的,mid 始终位于数组的前半部分。

另外,你有你的案子

    } else if (result > 0) {
        start = mid;
    } else if (result < 0) {
        end = mid;
    }

错了。

result = students[mid].returnLastName().compareToIgnoreCase(keyword);

students[mid] 的姓氏按字典顺序大于keyword 时返回一个正数,因此您需要更改end,而不是start

【讨论】:

  • 有趣。我修复了中间错误。我该怎么做才能解决我的问题?
  • 只是交换比较。您也可以使用mid-1mid+1else if (result &lt; 0) { start = mid+1; } else { end = mid-1; },因为您知道mid 不是正确的索引。
  • 你应该使用if (end &lt;= start),而不是if (end - start &lt;= 1)。如果 end == start+1mid 设置为 start,并且如果 end 是匹配项,那么您永远不会在现在的测试中尝试这样做。
  • 我会同意 Daniel Fisher 的回答。同时检查您的 while 循环,因为这可能不会检查数据中的姓氏。
  • 太棒了。现在对我来说真的很有意义!但是有一件事困扰着我,当我搜索它时,第一个元素 Amanda 和最后一个元素 zara 没有被输出。其余的都很好。
【解决方案2】:

不要在循环条件中使用不等式 -- while (start != end) -- 使用 while (start &lt; end)This is the typical approach。当您测试相等性时,您会假设 startend 在每次迭代中只改变一个,这可能不一定是真的。

【讨论】:

  • 很容易理解,如果数据之前没有被fileSorted 标记为排序,则数据会在bubbleSort 中排序。我们不希望这里有数百行代码。不过,我同意while (start &lt; end) 更合适。
  • 我同意,并编辑了我的答案。我只是关心数据在进入搜索方法之前发生了什么。
猜你喜欢
  • 1970-01-01
  • 2019-06-19
  • 1970-01-01
  • 2022-08-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
  • 2014-03-22
  • 1970-01-01
相关资源
最近更新 更多