繁体   English   中英

如何在数组 [i] = i 的数组 JavaScript 中查找元素?

[英]How to find elements in array JavaScript where array[i] = i?

我需要在arr[i] === i的数字数组中找到元素,这意味着该元素必须等于数组索引。
必须使用递归找到它们,而不仅仅是循环。
如果有人提供帮助,我将非常感激,因为我花了很多时间却无能为力。
我尝试使用二分搜索,但它不起作用。 最后我只有空数组。

 function fixedPointSearch(arr, low, high) { let middle = Math.floor((high - low) / 2); console.log( low, high, middle ) let arrRes = []; if (arr[middle] === middle) { arrRes.push(arr[middle]); } else if (arr[middle] > middle) { fixedPointSearch(arr, middle + 1, high); } else { fixedPointSearch(arr, low, middle - 1); } return arrRes; } const arr1 = [-10, -3, 2, 3, 6, 7, 8, 9, 10, 12, 16, 17]; console.log(fixedPointSearch(arr1, 0, arr1.length - 1));

要递归地执行此操作,您可能希望对越来越小的 arrays 进行递归,但这意味着您还需要更新每次调用时检查的索引。 最简单的方法之一就是在 function 的参数中包含一个索引,并在每次递归调用时递增它。 这是这样做的一种方法:

 const fixedPointSearch = ([x, ...xs] = [], index = 0) => x == undefined? []: [... (x === index? [x]: []), ... fixedPointSearch (xs, index + 1)] console.log ( fixedPointSearch([-10, -3, 2, 3, 6, 7, 8, 9, 10, 12, 16, 17]) )

该版本或以下版本是否更易于阅读尚有争议,但它们本质上是在做同样的事情:

const fixedPointSearch = ([x, ...xs] = [], index = 0) =>
  x == undefined
    ? [] 
  : x === index
    ? [x, ... fixedPointSearch (xs, index + 1)]
  : // else 
    fixedPointSearch (xs, index + 1)

但是,有一个潜在的问题。 在一个大数组上运行它,我们可以达到递归深度限制。 如果 function 是尾递归的,那么当 JS 引擎执行尾调用优化时,这个问题就会消失。 当然,我们不知道那会是什么时候,甚至它实际上会发生,即使它已经指定了五年。 但有时写作以利用它是有意义的,希望有一天它会成为现实,特别是因为这些仍然可以像非尾调用版本一样工作。

所以尾递归版本可能如下所示:

const fixedPointSearch = ([x, ...xs] = [], index = 0, res = []) =>
  x == undefined
    ? res
    : fixedPointSearch (xs, index + 1, x === index ? [...res, x] : res)

如果要查找所有元素,则应从数组的开头开始,而不是从中间开始并遍历所有索引。

递归的想法是定义结束条件

然后检查arr[i] === i是否更新results数组。

然后,您使用递增的索引和更新的results数组进行递归调用。

 function fixedPointSearch(arr, i, results) { // End condition of the recursion if (i === arr.length - 1 || arr.length === 0) { return results; } if (arr[i] === i) { results.push(i); } // Recursive call return fixedPointSearch(arr, i + 1, results); } const arr1 = [-10, -3, 2, 3, 6, 7, 8, 9, 10, 12, 16, 17]; console.log(fixedPointSearch(arr1, 0, [])); console.log(fixedPointSearch([], 0, [])); console.log(fixedPointSearch([9, 8, 7], 0, []));

对于递归,您需要一个结束条件。 就像是

 const findElementValueIsPositionInarray = arr => { let results = []; const find = i => { if (arr.length) { // as long as arr has values const value = arr.shift(); // get value results = i === value // check it? results.concat(value): results; return find(i+1); // redo with incremented value of i } return results; }; return find(0); } console.log(findElementValueIsPositionInarray([2,3,4,3,9,8]).join()); console.log(findElementValueIsPositionInarray([2,3,4,91,9,8]).join()); console.log(findElementValueIsPositionInarray([0,1,2,87,0,5]).join());
 .as-console-wrapper { top: 0; max-height: 100%;important; }

您可以通过在每个步骤中简单地缩短数组来解决此问题,无需额外的临时 arrays 和参数:

 const myArray = [0, 5, 2, 4, 7, 9, 6]; function fixedPointSearch(arrayToTest) { if (arrayToTest.length === 0) { return []; } const lastIndex = arrayToTest.length - 1; const lastItem = arrayToTest[lastIndex]; const remainingItems = arrayToTest.slice(0, lastIndex); return lastItem === lastIndex? [...fixedPointSearch(remainingItems), lastItem]: fixedPointSearch(remainingItems); } console.log(fixedPointSearch(myArray));

JavaScript 中的惯用解决方案使用Array.prototype.filter -

 const run = (a = []) => a.filter((x, i) => x === i) console.log(run([ 0, 1, 2, 3, 4, 5 ])) // [0,1,2,3,4,5] console.log(run([ 3, 3, 3, 3, 3, 3 ])) // [3] console.log(run([ 7, 1, 7, 3, 7, 5 ])) // [1,3,5] console.log(run([ 9, 9, 9, 9, 9, 9 ])) // []

上面应该清楚的是,这项工作不需要递归。 但是没有什么能阻止你使用它,如果你愿意的话——

 const filter = (test = identity, a = [], i = 0) => { /* base */ if (i >= a.length) return [] /* inductive: i is in bounds */ if (test(a[i], i)) return [ a[i], ...filter(test, a, i + 1) ] /* inductive: i is in bounds, a[i] does not pass test */ else return filter(test, a, i + 1) } const run = (a = []) => filter((x, i) => x === i, a) console.log(run([ 0, 1, 2, 3, 4, 5 ])) // [0,1,2,3,4,5] console.log(run([ 3, 3, 3, 3, 3, 3 ])) // [3] console.log(run([ 7, 1, 7, 3, 7, 5 ])) // [1,3,5] console.log(run([ 9, 9, 9, 9, 9, 9 ])) // []

我不知道您为什么要通过递归来实现它:-但无论如何,以下内容应该对您有所帮助:-

let ans = [];

function find(arr,index,ans)
{
  if(index==arr.length-1)
    {
      if(arr[index]==index){
        ans.push(arr[index])
    }
    return;
}
  if(arr[index]==index){
      ans.push(arr[index])
}
  find(arr,index+1,ans);
}
const arr1 = [-10, -3, 2, 3, 6, 7, 8, 9, 10, 12, 16, 17];
find(arr1,0,ans);
console.log(ans);

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM