【问题标题】:Mystery Array Object behavior for Array Reversal数组反转的神秘数组对象行为
【发布时间】:2016-07-03 06:26:51
【问题描述】:

我目前正在研究数据结构,并一直在探索 javascript。我一直在写一个反向数组就地方法来解决这个问题。我查看了有关数组对象、Object.prototype 和函数对象的文档,但我找不到正在发生的事情的答案。也许我有一个逻辑错误,这里是代码:

//Reverse Array in Place Exercise
Array.prototype.tRev = function()
{
    var nRay = this.valueOf(); //copy current instance of array

    for (var x = 0,y = this.length-1; x < this.length; x++,y--)
    {            
        this[x] = nRay[y];  //switch array element with copy of nRay (original elements)            
    } 
}

这个方法给了我不熟悉的结果。

var z = [1,2,3,4,5];
var z1 = [343,32423,2434,4,5,5,3];
var z2 = ['hello','hi','goodbye'];

z.tRev();  //console -- > Array [ 5, 4, 3, 4, 5 ]
z1.tRev(); //console -- > Array [ 3, 5, 5, 4, 5, 5, 3 ]
z2.tRev(); //console -- > Array [ "goodbye", "hi", "goodbye" ]

为了尝试调试,我编写了几个 console.logs 来跟踪当前实例和复制数组中的迭代器和数组元素。

var z = [1,2,3,4,5];
z.tRev();
undefined

 current x is = 1 new copy of y is = 5
 x iterator is = 0 z iterator is = 4
 new x is = 5 old copy of y is = 5

 current x is = 2 new copy of y is = 4
 x iterator is = 1 z iterator is = 3
 new x is = 4 old copy of y is = 4

 current x is = 3 new copy of y is = 3
 x iterator is = 2 z iterator is = 2
 new x is = 3 old copy of y is = 3

 current x is = 4 new copy of y is = 4
 x iterator is = 3 z iterator is = 1
 new x is = 4 old copy of y is = 4

 current x is = 5 new copy of y is = 5
 x iterator is = 4 z iterator is = 0
 new x is = 5 old copy of y is = 5

任何见解将不胜感激。

【问题讨论】:

标签: javascript arrays object data-structures iteration


【解决方案1】:
Array.prototype.tRev = function()
{
    var nRay = this.valueOf(); //copy current instance of array

    for (var x = 0,y = this.length-1; x < y; x++,y--)
    {      var tmp = this[x];      
        this[x] = this[y];  //switch array element with copy of nRay (original elements)  
        this[y] = tmp          
    } 
return this;
}

【讨论】:

  • 您可以删除var nRay 这一行。
【解决方案2】:

这里的主要问题是this.valueOf() 不会复制数组。如果你想要一份副本,你应该使用this.slice()。但是,如果您制作副本,那么就地进行反转有什么意义呢?

Array.prototype.tRev = function() {
  for (var x = 0; x < this.length / 2; x++) {
    var y = this.length - x - 1;
    var swap = this[x];
    this[x] = this[y];
    this[y] = swap;
  }
}

编辑:如果你喜欢使用 ES6:

Array.prototype.tRev = function() {
  for (var x = 0; x < this.length / 2; x++) {
    var y = this.length - x - 1;
    [this[y], this[x]] = [this[x], this[y]];
  }
}

【讨论】:

  • x &lt; this.length / 2
【解决方案3】:

你可以在 O(n/2) 时间内这样做。

var  z = [1,2,3,4,5],
    z1 = [343,32423,2434,4,5,5,3],
    z2 = ['hello','hi','goodbye'];
Array.prototype.tRev = function(){
                         var i = 0,
                           len = this.length,
                         limit = Math.floor(len/2);
                         while (i <= limit) [this[i],this[len-1-i++]] = [this[len-1-i],this[i]];
                         return this;
                       };

console.log(z.tRev()); // in place reversed
console.log(z1.tRev());
console.log(z2.tRev());

增加i 的东西只是很棘手。这个位置是 ES6 数组解构执行在数组交换中的最后一次调用..

【讨论】:

  • @Bergi OP 的算法和本主题下的剩余答案一直计数到最后,而这个只计数到 n/2 - 1。所以就是这样......加上 OP 的代码不是好好工作。那么问题是什么..?
  • 计算到 n 或 n/2 对复杂性没有影响。
  • @Bergi 是的,我知道……但不在我的书中。在我的书中,O(2n) 和 O(n) 之间的区别与 O(n) 和 O(n/2) 相同。
  • 奇怪的缩进。
  • @Redu:完全正确——它们之间没有区别。
猜你喜欢
  • 1970-01-01
  • 2018-04-25
  • 2016-10-06
  • 1970-01-01
  • 1970-01-01
  • 2020-08-30
  • 2021-05-03
  • 2018-12-04
  • 2021-06-16
相关资源
最近更新 更多