递归地反转数组中的元素
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" ]
想法:
如果我能以某种方式取出第一个元素并将其放入最后一个索引中,我的工作就完成了。
解释:
因为我们使用递归,所以我们可以将数组的第一个元素存储在堆栈中。
现在,我们知道后进先出的堆栈工作。所以,按照上面的原则,如果我数组的最后一个元素先入栈,如果我们可以先将最后一个元素压入一个空数组,那么我们就可以实现输出。
算法:
- 弹出数组的第一个元素
- 调用相同的函数,直到所有元素都被弹出并且数组为空。
- 压入空数组中已弹出的最后一个元素。
代码:
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) 的“递归思考”。
我想在 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))
这个一直在被复活,但是
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" ]
想法:
如果我能以某种方式取出第一个元素并将其放入最后一个索引中,我的工作就完成了。
解释:
因为我们使用递归,所以我们可以将数组的第一个元素存储在堆栈中。
现在,我们知道后进先出的堆栈工作。所以,按照上面的原则,如果我数组的最后一个元素先入栈,如果我们可以先将最后一个元素压入一个空数组,那么我们就可以实现输出。
算法:
- 弹出数组的第一个元素
- 调用相同的函数,直到所有元素都被弹出并且数组为空。
- 压入空数组中已弹出的最后一个元素。
代码:
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) 的“递归思考”。