【问题标题】:find the position of element in array?找到数组中元素的位置?
【发布时间】:2022-06-19 16:20:10
【问题描述】:

我的array of N integers 按非递减顺序排列。需要在数组中查找任何特定元素,如果找到则返回该数组的位置,否则返回-1

public static int find(int[] v, int bb) {
    int N = v.length;
    if (N == 0) {
        return -1;
    }
    int l = 0;
    int r = N - 1;
    while (l < r) {
        int m = (l + r) / 2;
        if (v[m] > bb) {
            r = m - 1;
        } else {
            l = m;
        }
    }
    if (v[l] == bb) {
        return l;
    }
    return -1;
}

我需要找出一个错误,即这对某些输入不起作用。我放弃了。

有什么建议吗?

【问题讨论】:

  • “非降序”是指它不是降序,还是说它是升序,但可能有重复的元素?另外,它不适用于哪些输入?
  • 对,它不是按降序排列的。并且需要找出并修复它不起作用的地方
  • 好的,如果你不知道它是按递增顺序排列的,你不应该尝试使用二分搜索。您可以按任何顺序单独检查每个元素,也可以先对数组进行排序,然后使用二进制搜索。

标签: java algorithm


【解决方案1】:

如果您想定位数组中第一个特定数字元素的索引,那么您可以执行以下操作:

public static int find(int[] v, int bb) {
    int found = -1;
    for (int i = 0; i < v.length; i++) {
        if (v[i] == bb) {
            found = i;
            break;
        }
    }
    return found;
}  

如果数组中有多个值与bb 相同,则上述方法将仅提供找到的第一个值。如果要返回数组中找到的bb所有 值的索引值,则需要返回索引值数组,例如:

public static int[] find(int[] v, int bb) {
    List<Integer> list = new ArrayList<>();
    int found = -1;
    for (int i = 0; i < v.length; i++) {
        if (v[i] == bb) {
            found = i;
            list.add(found);
        }
    }
    if (found == -1) { 
        list.add(found); 
    }
    return list.stream().mapToInt(d -> d).toArray();
} 

在上面的例子中使用了列表接口,因为它可以动态增长,因为我们不知道有多少bb 的值实际上将包含在数组中。 List 在返回之前被转换为 int[] 数组。

【讨论】:

    【解决方案2】:

    首先,我认为你应该给你的变量取一个合适的名字,而不仅仅是一个字符,这会让你的代码更容易理解。

    其次,您正在使用二进制 serach 算法来增加有序数组,如果您希望该代码正常工作,您必须使用递增有序数组。在这里,您有一个二进制搜索方法,它应该适用于递增的有序数组:

    public static int binarySeacrh(int [] list, int numSearched) {
        
        boolean found = false;
        int start = 0;
        int end = list.length - 1;
        int pos = -1;
    
        while(start <= end && !found){
            int middle=((start + end) / 2);
            if (numSearched == list[middle]){
                found = true;
                pos = middle;
            } 
            else if (list[middle] < numSearched){
                start = middle + 1;
            }else{
                end = middle - 1;
            }
        }
        
        return pos;
    }
    

    如果要在无序数组中搜索位置,则必须使用另一种类型的 serach 算法或先对数组进行排序。

    【讨论】:

    • 这不是真的。只要集合已排序,二进制搜索就可以工作,无论它是递增还是递减排序。
    • 是的,但是算法应该有一些变化,他/她使用的二进制搜索只适用于递增有序数组。如果你想在一个降序数组中搜索,你应该稍微改变一下 if / else 块,不是吗?
    • 二分搜索算法适用于递减和递增排序的集合。无论哪种情况,您都应该编写它。数组按递减顺序排列这一事实不应妨碍我们编写正确的通用算法。
    【解决方案3】:

    您的代码中有几个错误。首先,您需要在循环内而不是在循环外使用相等的大小写,否则您将不断移动您的范围,完全错过要找到的值。

    其次,当您使用r = m - 1; 将范围从“右侧”侧移动时,您需要对“左侧”侧执行相同的操作,否则您可能会无限循环。

    这是您的代码的固定版本:

    public static int find(int[] v, int bb) {
        if (v.length == 0) {
            return -1;
        }
    
        int l = 0;
        int r = v.length;
        int m;
    
        while (l < r) {
            m = (l + r) / 2;
            if (v[m] == bb) {
                return m;
            } else if (v[m] > bb) {
                r = m - 1;
            } else {
                l = m + 1;
            }
        }
    
        return -1;
    }
    

    附带说明,您可能希望将该 m 声明放在循环之外。在循环的每次迭代中重新声明变量并不是那么有效,也不是最佳实践。

    【讨论】:

      猜你喜欢
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 2020-05-23
      • 2016-08-08
      • 1970-01-01
      相关资源
      最近更新 更多