【问题标题】:Find the largest index occurrence of a number using binary search使用二进制搜索查找数字的最大索引出现
【发布时间】:2017-04-18 21:44:38
【问题描述】:

此代码生成一个随机数,按升序对其进行排序并进行二进制搜索以找到目标值。我的问题是如何修改此代码以找到给定目标的最大索引。例如数组有 { 1, 2 , 3, 5, 5, 5, 5},目标是 5,所以输出应该是 6 而不是 3。谢谢。

    import java.util.*;
    public class Sort
    {
        public static void main(String args[])
        {
            Scanner in = new Scanner(System.in);
            System.out.print("How many numbers do you want? ");
            int howMany = in.nextInt();
            int [] myArray =  getSortedRandomArray(howMany);
            System.out.print("\nFor what value would you like to search? ");
            int target = in.nextInt();
            int index = bsearch ( myArray, target);
            if (index >= 0)
            {
                System.out.println("The value " + target + " occurs at index " + index);
            }
            else
            {
                System.out.println("The value " + target + " does not occur in the array. ");
            }   
        }

  public static int bsearch(int[] arr, int key)
    {
    int lo = 0, hi = arr.length - 1;
    {
        while (lo < hi) 
        {
            int mid = (lo + hi) / 2;
            if (arr[mid] <= key)
                lo = mid + 1;
            if (arr[mid] > key)
                hi = mid;
        }
        if (arr[lo] == key) {
            return lo;
        }
        else if ((arr[lo] != key) && (arr[lo-1] == key)){
            return lo - 1;
        }
        else{
        System.out.print("The value " + key + " does not occur in the array. "); 
    } 
        return -1 ;
    } 
   public static int[] getSortedRandomArray (int howMany)
    {
        int[] returnMe = new int [howMany];
        Random rand = new Random();
        for (int i = 0; i < howMany ; i++) 
            returnMe[i] = rand.nextInt(Integer.MAX_VALUE) + 1;
        for (int i = 1; i <= (howMany - 1); i++)
        {
            for (int j = 0; j <= howMany - i -1; j++)
            {
                int tmp = 0;
                if (returnMe[j] > returnMe[j+1])
                {
                    tmp = returnMe[j];
                    returnMe[j] = returnMe[j + 1];
                    returnMe[j + 1] = tmp; 
                }   
            }  
        }
        System.out.print("Here is a random sorted array: ");
        for ( int i = 0; i < howMany; i++)
            System.out.print(returnMe[i] + " ");     
        return returnMe;
    }

【问题讨论】:

  • 我??哈哈,不。对不起,先生,如果那不礼貌! @OusmaneMahyDiaw
  • 没有问题,只是写的都是大写而已。
  • 好吧,您已经找到了具有该值的一个元素的索引。并且具有相同值的所有其他元素彼此相邻。那么......你认为你怎么能找到它?
  • @AndyTurner 我曾想过使用循环,但如果有 100 个数字都具有相同的目标值,那会不会效率低下?
  • @rockster 就这么多? :) 请记住,正确性总是比速度更重要。用简单的方法来做,然后在分析显示这是一个问题时担心性能。

标签: java search binary-search


【解决方案1】:

您可以通过修改二进制搜索算法代码来做到这一点:

 public static int bsearch(int[] arr, int key) {
    int lo = 0, hi = arr.length - 1;
    while (lo < hi) {
        int mid = (lo + hi) / 2;
        if (arr[mid] <= key)
            lo = mid + 1;
        if (arr[mid] > key)
            hi = mid;
    }

    if (arr[lo] == key) {
        return lo;
    }
    else {
        return lo - 1;
    }
}

此代码改为搜索大于 key 的第一个数字。这可以是任何数字,6 或 10000,没关系。如您所见,如果 arr[mid] 等于 key,代码仍将在区间 [mid, hi] 上运行。为什么最后那两个回来了?好吧,如果输入数组和你给的一样,lo 将作为最后 5 的索引结束,但是如果我们在输入数组的末尾添加另一个数字,lo 将是最后 5 后面的数字的索引。因此,我们有两种不同的情况。

此外,您不能像其他答案那样使用线性循环来执行此操作,因为这会将算法简化为 O(n),并且最终只是对简化数组进行线性搜索。

【讨论】:

  • 也谢谢你的解释 :) 帮助很大
  • 没问题。乐意效劳。如果您想了解更多信息,我建议您现在尝试使用这种算法。如果您确实愿意,可以做一些有趣的事情:修改算法,使其即使 key 不在 arr 中也能正常工作,例如当 arr = {1, 3, 6, 8} 和 key = 5 时。
  • 我使用了这段代码(在 bsearch 下的问题中编辑),如果数组中没有数字但当数组为 { 5,6,9,9,9,9 时它会起作用..} 并且目标是 4。它在else if ((arr[lo] != key) &amp;&amp; (arr[lo-1] == key)){@leonz 处给出了一个错误提示 arrayIndexOfBoundException
【解决方案2】:

如果你稍微更新一下你的 bsearch 算法,你可以让它递归地寻找更高的匹配。然而,这是否比线性循环更有效将取决于输入数组的样子。

public static int bsearch(int[] arr, int key, int lo, int hi) {
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        if (arr[mid] == key) {
            System.out.println("The value " + key + " is found at " + mid);
            int higherResult = bsearch(arr, key, mid + 1, hi);
            if (higherResult < 0) {
                return mid;
            }
            return higherResult;
        }
        if (arr[mid] < key) {
            lo = mid + 1;
        } else {
            hi = mid - 1;
        }
    }
    return -1;
}

【讨论】:

    猜你喜欢
    • 2018-06-20
    • 1970-01-01
    • 2019-11-10
    • 2019-07-15
    • 2015-10-11
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多