反向阵列到位

时间:2015-09-05 22:57:10

标签: javascript arrays sorting for-loop

为什么这个函数reverseArrayInPlace不起作用?我想简单地完成函数所说的内容 - 颠倒元素的顺序,以便结果在同一个数组arr中结束。我选择在函数中使用两个数组来做到这一点。到目前为止,它只是按顺序返回元素......

    var arr = ["a","b","c","d","e","f"]
    var arr2 = []

    var reverseArrayInPlace = function(array){

      var arrLength = array.length
      for (i = 0; i < arrLength; i++) {
        arr2.push(array.pop())
        array.push(arr2.shift())
      }
    }

    reverseArrayInPlace(arr)

10 个答案:

答案 0 :(得分:7)

这是一种使用就地算法反转数组的简单方法

function reverse (array) {
  var i = 0,
      n = array.length,
      middle = Math.floor(n / 2),
      temp = null;

  for (; i < middle; i += 1) {
     temp = array[i];
     array[i] = array[n - 1 - i];
     array[n - 1 - i] = temp;
  }
}

你&#34;分裂&#34;阵列成了一半。嗯,不是真的,你只是在上半场迭代。然后,使用公式n - 1 - i找到与当前索引相对于中间对称的索引,其中i是当前索引。然后使用临时变量交换元素。 公式是正确的,因为它将交换:

0 <-> n - 1
1 <-> n - 2

等等。如果元素的数量是奇数,则中间位置不会受到影响。

答案 1 :(得分:2)

我认为你想要一种简单的方法来反转数组。希望它能帮到你

var yourArray = ["first", "second", "third", "...", "etc"]
var reverseArray = yourArray.slice().reverse()

console.log(reverseArray)

你会得到

["etc", "...", "third", "second", "first"]

答案 2 :(得分:1)

pop()将删除数组的最后一个元素,push()会将一个项追加到数组的末尾。所以你反复弹出并推动数组的最后一个元素。

您可以使用push,而不是使用splice,它允许您在数组中的特定位置插入项目:

var reverseArrayInPlace = function (array) {
    var arrLength = array.length;
    for (i = 0; i < arrLength; i++) {
        array.splice(i, 0, array.pop());
    }
}

(请注意,您不需要中间数组来执行此操作。使用中间数组实际上不是就地反向。只需弹出并插入当前索引。)

此外,有趣的评论 - 您可以跳过最后一次迭代,因为第一个元素将始终在length - 1次迭代后的最后位置结束。因此,您可以安全地迭代arrLength - 1次。

我还想补充一点,Javascript在数组上有一个内置的reverse()方法。因此["a", "b", "c"].reverse()将产生["c", "b", "a"]

一个真正的就地算法将执行交换到数组的中间,并在另一侧使用相应的元素:

var reverseArrayInPlace = function (array) {
    var arrLength = array.length;
    for (var i = 0; i < arrLength/2; i++) {
        var temp = array[i];
        array[i] = array[arrLength - 1 - i];
        array[arrLength - 1 - i] = temp;
    }
}

答案 3 :(得分:1)

您正在使用arr作为参数调用函数,因此arrarray都引用函数内的相同数组。这意味着代码与:

相同
var arr = ["a","b","c","d","e","f"]
var arr2 = []

var arrLength = arr.length;
for (i = 0; i < arrLength; i++) {
  arr2.push(arr.pop())
  arr.push(arr2.shift())
}

第一个语句从arr获取最后一项,并将其放在arr2中。现在你有:

arr = ["a","b","c","d","e"]
arr2 = ["f"]

第二个语句从arr2获取第一个(也是唯一的)项目并将其放在arr中的最后一个项目中:

arr = ["a","b","c","d","e","f"]
arr2 = []

现在你回到了你开始的地方,并且循环中的所有迭代都会发生同样的事情。最终结果是没有任何改变。

要使用poppush将项目反转放在另一个数组中,您只需移动项目直到数组为空:

while (arr.length > 0) {
  arr2.push(arr.pop());
}

如果您想要将它们移回(而不是仅仅使用新数组),则可以使用shiftarr2push的开头获取项目,以便将它们放在结束arr

while (arr2.length > 0) {
  arr.push(arr2.shift());
}

通常不使用堆栈/队列操作来执行反转,您只需将项目从头开始交换。这要快得多,而且你不需要另一个数组作为缓冲区:

for (var i = 0, j = arr.length - 1; i < j; i++, j--) {
  var temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

这就像这样交换对:

["a","b","c","d","e"]
  |   |       |   |
  |   +-------+   |
  +---------------+

答案 4 :(得分:1)

由于我对此作业的约束,这就是我想出如何解决问题的方法:

var arr = ["a","b","c","d","e","f"]
var arr2 = []

var reverseArrayInPlace = function(array){

      var arrLength = array.length
      for (i = 0; i < arrLength; i++) {
        arr2.push(array.pop())
      }
      for (i = 0; i < arrLength; i++) {
        array[i] = arr2.shift()
      }
    }

      reverseArrayInPlace(arr)

感谢您的帮助!



*****编辑******

对于你们所有感兴趣的人,我都是通过这个帖子以及我自己的心理设备的帮助重新编写的......这在这一点上是有限的。这是它:

    arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]
    arr2 = ["a","b","c","d","e","f"]
    arr3 = [1,2,3]
    arr4 = [1,2,3,4]
    arr5 = [1,2,3,4,5]


    var reverseArrayInPlace2 = function(array) {

      var arrLength = array.length
      var n = arrLength - 1
      var i = 0
      var middleTop = Math.ceil(arrLength/2)
      var middleBottom = Math.floor(arrLength/2)

      while (i < Math.floor(arrLength/2)) {

        array[-1] = array[i]
        array[i] = array[n]
        array[n] = array[-1]
        // console.log(array)
        i++
        n--

      }

      return array
    }

    console.log(reverseArrayInPlace2(arr))
    console.log(reverseArrayInPlace2(arr2))
    console.log(reverseArrayInPlace2(arr3))
    console.log(reverseArrayInPlace2(arr4))
    console.log(reverseArrayInPlace2(arr5))

P.S。改变全局变量有什么问题?替代方案是什么?

答案 5 :(得分:1)

这是我没有临时数组的解决方案。没有什么是开创性的,只是一些提议的解决方案的缩短版本。

let array = [1, 2, 3, 4, 5];

 for(let i = 0; i<Math.floor((array.length)/2); i++){
     var pointer = array[i];
     array[i] = array[ (array.length-1) - i];
     array[(array.length-1) - i] = pointer;
 }

 console.log(array);
 //[ 5, 4, 3, 2, 1 ]

答案 6 :(得分:1)

如果您正在使用Eloquent Javascript,该练习明确指出不使用新阵列进行临时值存储。本书后面的线索介绍了解决方案的结构,就像Stefan Baiu的回答一样。

我在这里发布的答案比Stefan使用更少的行,因为我认为在函数内的变量中存储像array.length这样的值是多余的。它也使我们的初学者更容易阅读。

function reverseArrayInPlace(array) {

    for (var z = 0; z < Math.floor(array.length / 2); z++) {

        var temp = array[z];
        array[z] = array[array.length-1-z];
        array[array.length-1-z] = temp;

    }

    return array;
}

答案 7 :(得分:1)

我知道这是一个老问题,但是我想出了一个上面没有看到的答案。它类似于上面批准的答案,但是我使用数组解构而不是临时变量来交换数组中的元素。

free

答案 8 :(得分:0)

  • 此解决方案使用
  • 的简写

var arr = ["a","b","c","d","e","f"]

const reverseInPlace = (array) => {
  let end = array.length;

  while(end--)
     array.unshift(array.pop());

  return array;
}

reverseInPlace(arr)

答案 9 :(得分:0)

private Form<Product> productForm;

@Inject
public ProductsController(FormFactory formFactory) {
    this.productForm = formFactory.form(Product.class);
}