【问题标题】:Javascript Algorithm Practice Removing Negatives From ArrayJavascript算法练习从数组中去除负数
【发布时间】:2015-04-21 17:40:36
【问题描述】:

我很难把我的大脑包裹在这个周围:/

  • (删除负数)给定一个包含多个值的数组 X(例如 [-3,5,1,3,2,10]),编写一个删除数组中所有负数的程序。一旦你的程序完成,X 应该只由正数组成。 这样做不创建临时数组,只使用 pop 方法删除数组中的任何值。

我的想法是通过数组编写一个循环。如果 X[i] 为负数,则开始另一个循环交换 X[j] 和 X[j+1] 直到数组末尾。 (保留数组的顺序)然后使用 pop()。

当我运行脚本时,看起来循环是无限的。此外,如果连续有两个负值,第二个可能会在 i 的下一次迭代中被跳过。有没有更简单的方法?

var X = [1,-6,-7,8,9];
//test= [1,-7,8,-6,9]
temp = 0

for (i = 0;i<X.length-1;i++){
    if (X[i]<0){
        for (j = i;j<=X.length-1;j++){
            X[j] = temp
            X[j] = X[j+1] 
            X[j+1] = temp
        }
        if(X[X.length-1] < 0){X.pop()}
    }
};
console.log(X);

【问题讨论】:

  • 您提到保留数组的顺序,但为什么呢?描述中没有提到任何关于保持秩序的内容。
  • 你可以Array.splice吗?
  • 你是无限循环的,因为你的j 循环中有X[j+1] = temp。当j 等于X.length - 1 时,这一行将在数组中添加一个额外的条目,导致它再次循环,再次添加和循环并添加......永远

标签: javascript arrays algorithm


【解决方案1】:

与您提到的方法非常相似,除了没有理由维持秩序(除非描述中缺少)。 反向循环,当找到负数时,将其与最后一个元素交换并弹出。如果我们首先从末尾弹出所有负数,我们知道最后一个元素不是负数。

var x = [1, -6, -7, 8, 9, -3];

// strip all negatives off the end
while (x.length && x[x.length - 1] < 0) {
  x.pop();
}

for (var i = x.length - 1; i >= 0; i--) {
  if (x[i] < 0) {
    // replace this element with the last element (guaranteed to be positive)
    x[i] = x[x.length - 1];
    x.pop();
  }
}

document.body.innerHTML = '<pre>' + JSON.stringify(x, null, 4) + '</pre>';

此解决方案具有线性复杂性,因为它只迭代列表一次。

【讨论】:

【解决方案2】:

先对数组进行排序,使负数在最后。
我们可以使用将负数移到末尾的回调进行排序。

然后向后迭代并删除带有pop 的最后一个索引,只要它们是负数。

我们剩下的是正值。

var X = [-3, 5, 3, 8, 1,-6,-7,8,9];

X.sort(function(a,b) {
    return b - a;
});

for (var i=X.length; i--;) {
    if ( X[i] < 0 ) X.pop();
}

document.body.innerHTML = '<pre>' + JSON.stringify(X, null, 4) + '</pre>';

【讨论】:

  • 也可以是(几乎)单行与filter(),即x.filter(function(el) { if (el &lt; 0) { return false; } return true; });
  • 不会过滤返回一个新数组,我认为重点是在不创建临时数组的情况下更改数组?
  • @jdphenix filter 创建一个新数组。
  • @JamesMontagne - 也许,这是我能想到的最好的,当使用pop 时,pop 的值必须在最后,不能在中间弹出?跨度>
  • 确实,很好。我想知道为什么会有不创建临时数组的要求。这似乎是 JavaScript 程序的向后要求,因为它具有几乎满足他们需要的功能的内置功能(即filter())
【解决方案3】:

已经有很多好的答案了。这是一个简单的过滤器,它不对数组进行排序并使用辅助数组索引j &lt;= i:

function removeNeg(arr) {
    var j = 0;

    // filter array
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] >= 0) arr[j++] = arr[i];
    }

    // pop excess elements
    while (j < arr.length) arr.pop();
}

这确实是 C 程序员对 James Montagne 的回答的方法,更简洁,因为它会随你而去。

【讨论】:

    【解决方案4】:
    var x = [1, -6, -7, 8, 9];
    var i = 0;
    while (i < x.length) {
        if (x[i] < 0) {
            x[i] = x[x.length - 1];
            x.pop();
        } else {
            i++;
        }
    }   
    

    只是pop,没有使用Array的其他方法

    【讨论】:

      【解决方案5】:

      这是一个非常简单的解决方案,不需要排序。对于每个元素,移动它,如果它不是负数,则推动它。执行此操作的次数等于数组大小。这可以通过 shift/push 或 pop/unshift 来完成。

      var origLen = X.length;
      
      for(var i = 0; i < origLen; i++) {
        var val = X.pop();
      
        if(val > 0)
           X.unshift(val);
      }
      

      【讨论】:

      • 但是现在你使用shift从数组中删除,而不是pop
      猜你喜欢
      • 2018-09-15
      • 2012-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      相关资源
      最近更新 更多