简体   繁体   English

如何在分治法二分查找中找到数字的索引?

[英]How do i find the index of the number in a divide and conquer binary search?

I can use the divide and conquer binary search to find the number i want but how can i find the index of the number in the original array without using for loop and indexOf? 我可以使用分治法二分查找法找到我想要的数字,但是如何在不使用for循环和indexOf的情况下找到原始数组中数字的索引?

function search(array, value) {

    var midpoint = Math.floor(array.length / 2)

    if (value > array[midpoint]) {
        var slicedArray = array.slice(midpoint)
    } else {
        var slicedArray = array.slice(0,midpoint)
    }
    return slicedArray[Math.floor((slicedArray.length/2))] === value ? value : search(slicedArray, value)
}

console.log(search([1,3,16,22,31,33,34], 34))

You can and should condense this code substantially, but I've left it in a longer form to better illustrate the concepts. 您可以并且应该实质上压缩该代码,但为了使这些概念更好地说明,我将其保留了较长的形式。

function search(array, value) {
    if (array.length == 0)
        return NaN;

    var midpoint = Math.floor(array.length / 2);

    if (array[midpoint] === value)
        return midpoint;

    if (array[midpoint] < value)
        return search(array.slice(midpoint+1),value) + midpoint + 1;

    if (array[midpoint] > value) 
        return search(array.slice(0,midpoint),value);
}

When you write a recursive function, the first two questions you should always ask yourself are "How do I know I'm done?" 在编写递归函数时,您应该经常问自己的前两个问题是:“我怎么知道我已经完成了?” and "No really, is there any way this could fail to reach a completion condition?" 和“不,这是否有可能无法达到完成条件?”

You want to make certain you have covered every possible state. 您想确定已覆盖所有可能的状态。 In this case, there are four: 在这种情况下,有四个:

  • The array is empty. 数组为空。
  • The value at the midpoint of the array is equal to your search value. 数组中点的值等于您的搜索值。
  • The value at the midpoint of the array is less than your search value. 数组中点的值小于您的搜索值。
  • The value at the midpoint of the array is greater than your search value. 数组中点的值大于您的搜索值。

Using NaN as the 'search failed' return value is convenient because it avoids needing null-checking conditional logic around returning the value from recursion back up the chain; NaN用作“搜索失败”的返回值很方便,因为它避免了在递归返回链中返回值时需要进行空检查条件逻辑。 NaN plus a number equals NaN . NaN加一个数字等于NaN

You don't need to know and shouldn't try to calculate the index of the search value in the original array at the moment you find it, several recursive calls later. 您无需知道,也不应尝试在找到原始数组时计算搜索值的索引,以后将进行几次递归调用。 It's the calling instance's job to combine what it knows (its own midpoint) with the result of the recursion and return a useful value back up the chain. 调用实例的工作是将其知道的内容(自己的中点)与递归结果相结合,并在链中返回有用的值。 In fact, no particular call to this function should 'know' whether it was the original call or a recursion. 实际上,对此函数的任何特定调用都不应该“知道”它是原始调用还是递归。 If you ever find yourself NEEDING to know the answer to that question, it's a warning flag that you should re-examine your logic. 如果您发现自己想知道该问题的答案,那是一个警告信号,您应该重新检查您的逻辑。

You can have a wrapper function _binarySearch to do the actual binary search, along with taking two additional parameters l, r , whereas you can call search with just two parameters array, value 您可以使用包装器函数_binarySearch进行实际的二进制搜索,同时使用两个附加参数l, r ,而您可以仅使用两个参数array, value调用search

function _binarySearch(array, value, l, r) {
if (l > r) return -1;

var midPoint = Math.floor((l + r) / 2);

if (value == array[midPoint])
    return midPoint;

else if (value > array[midPoint])
    return _binarySearch(array, value, midPoint + 1, r);

else
    return _binarySearch(array, value, l, midPoint - 1);
}

function search(array, value) {
    return _binarySearch(array, value, 0, array.length);
}

If you want to know the first occurrence of an element, the worst case time complexity of the algorithm is not O(log n) anymore, it degenerates to O(n) . 如果您想知道元素的首次出现,则算法的最坏情况下的时间复杂度不再是O(log n) ,它会退化为O(n)

This modification becomes necessary 进行此修改是必要的

if (value == array[midPoint]) {
    while(midPoint > -1 && array[midPoint] == value)
        --midPoint;

    return midPoint + 1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 javascript 中找到数组中最小数字的索引 - How do I find the Index of the smallest number in an array in javascript JavaScript:如何使用二进制搜索在给定范围内的排序数组中查找数字 - JavaScript: how do I use binary search to find numbers in a sorted array within a given range 如何在二叉搜索树中找到最小的 n 个元素? - how do you find the smallest n elements in a binary search tree? 我想通过文本输入从用户那里获得两个整数,找到两个数字之间的差并将该数字除以25。我该怎么做? - I want to get two integers from a user via a text input, find the difference between the two numbers and divide that number by 25. How do I do this? 是动态编程还是分而治之? - Is this dynamic programming or divide and conquer? 如何在方表中找到一个数字所属的一组数字的索引? - How do I find the index of the group of numbers a number belongs to in a square table? 如何找到对象的索引? - How do i find index of my object? 如何从最大到最小对二叉搜索树进行排序? - How do I sort a Binary Search Tree from greatest to least? 如何停止二叉搜索树遍历? - How do I stop a Binary Search Tree Traversal? 当我在 Javascript 中将像 12330 这样的数字除以 100 时,如何保留最后的零 - how do I retain the the zero at the end when I divide a number like 12330 by 100 in Javascript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM