递归地反转数组中的元素

Recursively Reverse the Elements in an Array

我想在 javascript 中编写一个递归函数,returns 一个元素反转的数组。此代码生成以下错误:

undefined is not a function

function reverseArray (toBeReversed){
  var reversed = [];

  function reverser (toBeReversed){
    if (toBeReversed.length == 1)
      reversed.push(toBeReversed[0]);
    else {
      reversed.push(toBeReversed.lastOfIndex(0)); //error on this line
      reverser(toBeReversed.slice(-1));
    }
  }

  reverser(toBeReversed);
  return reversed;
}

lastOfIndex 不是函数,您可能想使用 lastIndexOf。这是一个类似的方式:

function reverseArray (toBeReversed){
  var reversed = [];

  function reverser (toBeReversed){
    if (toBeReversed.length !== 0){
      reversed.push( toBeReversed.pop() );
      reverser( toBeReversed );
    }
  }

  reverser(toBeReversed);
  return reversed;
}

尝试

function reverseArray (arr) {
  return (function reverser(r, t) {
    r.push(t.splice(-1, 1)[0]);
    return !!t.length ? reverser(r, t) : r
  }([], arr));
};

function reverseArray (toBeReversed) {
  return (function reverser(r, t) {
r.push(t.splice(-1, 1)[0]);
return !!t.length ? reverser(r, t) : r
  }([], toBeReversed));
};

var rev = document.getElementsByTagName("pre")[0];
document.getElementsByTagName("button")[0]
.addEventListener("click", function(e) {
  rev.innerText = "[" + reverseArray(JSON.parse(rev.innerText)) + "]"
})
<pre>[1,2,3,4,5,6,7]</pre><button>click</button>

这就是我的处理方式:

function reverse(arr) {
  var result = [];
  var count = arr.length;

  function recur() {
     if (result.length < arr.length) {
       result.push(arr[--count]);
       return recur();
     } else {
       return result;
     }
  }

  return recur();
}

用法:

var letters = ["a", "b", "c", "d", "e", "f", "g", "h"];
var reversed = reverse(letters);

输出:

console.log(reversed);
//=> ["h", "g", "f", "e", "d", "c", "b", "a"]

// Original array is unmodified
console.log(letters);
//=> ["a", "b", "c", "d", "e", "f", "g", "h"]

经典的递归实现是

function reverse(a) {
    if (!a.length) return a;
     return reverse(a.slice(1)).concat(a[0]);
}

您不需要任何循环、累加值的数组、函数内的函数或任何其他机制。

如果您更喜欢编写少量单行代码以使您的代码更具可读性,那么

function head(a)    { return a[0];         }
function tail(a)    { return a.slice(1);   }
function push(a, v) { a.push(v); return a; }
function empty(a)   { return !a.length;    }

function reverse(a) { 
    if (empty(a)) return a;
    return push(reverse(tail(a)), head(a)); 
}

这个小程序有属性可以"read"为英文,我觉得更多的程序应该有。在这种情况下是

The reverse of an array is (1) empty, if it is empty; (2) otherwise, the result of adding the head to the end of the reverse of the tail.

不幸的是,即使在提供优化尾递归的 JS 实现中(恰好 none 在这个时间点),它也不会在这种情况下应用,因为 JS 必须保留堆栈来调用 concat 每次 reverse 的结果。我们可以写一些可优化的东西吗?是的,通过携带另一个值,即到目前为止反转数组的结果:

function unshift(a, v) { a.unshift(v); return a; }

function reverse(a) { return _reverse(a, []); }

function _reverse(a, result) {
    if (empty(a)) return result;
    return _reverse(tail(a), unshift(result, head(a)));
}

或者如果您愿意

function reverse(a) { 
    return function _reverse(a, result {
        if (empty(a)) return result;
        return _reverse(tail(a), unshift(result, head(a)));
    }(a, []);
}

这不是很干净,但给我们带来的好处是仍然可以思考递归,没有与递归相关的正常堆栈开销。

const recursiveRev = arr => arr.length === 0 || arr.length === 1 ? arr : arr.slice(arr.length-1).concat(recursiveRev(arr.slice(-arr.length, -1)));

这是我对原始数组进行操作的解决方案。

   function reverseArr(arr, i, j){
      if(i < j){
        var temp1 = arr[i];
        arr[i] = arr[j];
        arr[j] = temp1;
        i++;
        j--;
        return reverseArr(arr,i,j);
      } else if(i === j ){
        return arr;
      }
    }
    var originalArr = [1,5,7,3,2,9,11];
    result = reverseArr(originalArr, 0, originalArr.length-1);
    console.log(result);

Link 到 fiddle:https://jsfiddle.net/octopuscode/opyes4nd/2/

我使用递归得出这个答案

function reverse(arr) {
    return (arr.length > 1) ? [arr.pop()].concat(reverse(arr)) : arr.pop();
}

const dataSet = [0, 1, 2, 3, 4];

console.log(reverse(dataSet));

let arr = ["1","2","3"]; //declaration of array

function reverseArr(param){
  let i=param.length; //set counter i to the array length
  
  if(i==0){ //when to exit recursion
    return;
  }
  
  console.log(param[i-1]) //what to do until you exit,[i-1] because arrays are 0-based
  param.pop(param[i-1]) //pop already printed element from array
  
  reverseArr(param) //pass the new array and invoke function again
}

reverseArr(arr)

这是我的反向函数解决方案:

  • 不改变输入数组。

function reverser = (array) => {
  const reversed = [];
  for (let i = array.length-1; i >= 0; i-- ) {
    if (Array.isArray(array[i])) {
      reversed.push(reverser(array[i]))
    } else {
      reversed.push(array[i])
    }
  }
  return reversed;
}

const arr1 = [1,2,3,4,5,6,7,8,9]
const arr2 = [[1,2,3],[4,5,6],[7,8,9]]
const arr3 = [[[1,2],[3]],[[4,5],[6]],[[7,8],[9]]]

console.log(reverser(arr1))
console.log(reverser(arr2))
console.log(reverser(arr3))

这个一直在被复活,但是 似乎很少有任何改进。但是在现代 JS 中,该算法有更好的语法:

const reverse = ([x, ...xs]) =>
  x == undefined ? [] : [... reverse (xs), x]

console .log (reverse ([9, 0, 3, 5, 7, 6, 8]))

使用递归简单实现一个非常简单的算法-

I/P : ["h" , "e", "l", "l" , "o"] O/P: [ "o" , "l", "l", "e", "h" ]

想法:

如果我能以某种方式取出第一个元素并将其放入最后一个索引中,我的工作就完成了。

解释:

因为我们使用递归,所以我们可以将数组的第一个元素存储在堆栈中。

现在,我们知道后进先出的堆栈工作。所以,按照上面的原则,如果我数组的最后一个元素先入栈,如果我们可以先将最后一个元素压入一个空数组,那么我们就可以实现输出。

算法:

  1. 弹出数组的第一个元素
  2. 调用相同的函数,直到所有元素都被弹出并且数组为空。
  3. 压入空数组中已弹出的最后一个元素。

代码:


    function reverseArray (s) {
    if(s.length === 0) { // base case of the recursion
        return []
    }

    let v = s.shift(); // Pop out the first element
    reverseArray(s); // repeat the operation for the next element
    s.push(v); // Once base case is reached start pushing the last popped element in the array
    return s;
}


console.log(reverseArray(["h" , "e", "l", "l" , "o"]))

注意:如果您不清楚递归的工作原理、什么是调用堆栈等,您可能想阅读埃里克·罗伯茨 (Eric Roberts) 的“递归思考”。