【问题标题】:Java Leftmost Binary SearchJava 最左二叉搜索
【发布时间】:2014-11-10 20:45:21
【问题描述】:

我正在尝试修改递归二进制搜索函数,以便在数组包含该元素的倍数的情况下找到该元素的最左侧索引。

import java.util.*;
import java.util.Arrays;
import java.io.File;
import java.io.IOException;

public class LeftmostBinarySearch {

    private static int myBinarySearch(int key, int[] a, int lo, int hi) {
    if (lo > hi) {
        return -1;
    }
    int mid = lo + (hi - lo) / 2;
    if (key < a[mid]) {
        return myBinarySearch(key, a, lo, mid - 1);
    } else if (key > a[mid]) {
        return myBinarySearch(key, a, mid + 1, hi);
    } else {
        return mid;
    }
}

    public static int myBinarySearch(int key, int[] a) {
    return myBinarySearch(key, a, 0, a.length - 1);
}

    public static void main(String[] args) throws IOException {
        String fileName = args[0] + ".txt";
        System.out.println(fileName);
        Scanner scanner = new Scanner(new File(fileName));
        int[] data = new int[7];
        int i = 0;
        int j = 0;

        while (scanner.hasNextInt()) {
            data[i] = scanner.nextInt();
            i++;
        }
        Arrays.sort(data);
        System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", " 0",
                "  ", " 1", "  ", " 2", "  ", " 3", "  ", " 4", "  ", " 5", "  ", " 6\n");
        System.out.format("%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s%2s", data[j],
                "  ", data[j + 1], "  ", data[j + 2], "  ", data[j + 3], "  ",
                data[j + 4], " ", data[j + 5], "  ", data[j + 6] + "\n");

        int input = new Scanner(System.in).nextInt();

        while ((Integer) input != null) {
            int key = input;
            System.out.println(data[0]);
            if (myBinarySearch(key, data) != -1) {
                System.out.println(input + " found: "
                        + myBinarySearch(key, data));
            }
            input = new Scanner(System.in).nextInt();
        }
    }
}

我从中得到的输出是:

C:\Users\Shirley\algs4>java LeftmostBinarySearch mydata
 0   1   2   3   4   5   6
10  20  20  30  40  40  40
10
10 found: 0
20
20 found: 1
30
30 found: 3
40
40 found: 5

我尝试将计算 mid 的方式更改为 (hi + lo - 1)/2,它适用于 40,给出索引 3,但对于 20,它给出索引 2。

【问题讨论】:

    标签: java arrays search integer binary-search


    【解决方案1】:

    您需要查看if(key == a[mid])。如果相等,则需要检查左边的最后一个元素是否相同,直到找到不同的元素。

    在您向左或向右分支之前应进行以下检查

    if (key == a[mid]) {
        while (--mid >= 0) {
            if (key != a[mid]) {
                break;
            }
        }
        return ++mid;
    }
    

    【讨论】:

    • 然而,这引入了另一对决策块和循环并增加了算法的复杂性,是否有使用“标准”实现的优化方法,或者应该使用 Hermann Bottenbruch 的替代程序 -> en.wikipedia.org/wiki/…
    【解决方案2】:

    问题出在最后一行:

    else return mid;
    

    您的列表包含重复项,因此 mid 可能不是最左侧的匹配项。所以试试:

    else {
      while(--mid>=0) {
        if (a[mid]!=key) break;
      }
      return mid+1;
    } 
    

    【讨论】:

    • 做到了。最后我并没有考虑这样做。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多