0

誰かがこのコードをデバッグできますか? 私は一生、(実行時)エラーを見つけることができません:

function generate_fibonacci(n1, n2, max, out){
    var n = n1+n2;
    if(n<max){
        out.push(n);
        generate_fibonacci(n2, n, max, out);
    }
}

function generate_fibonacci_sequence(max){
    var out = [1];
    generate_fibonacci(0, 1, max, out);
    return out;
}

function remove_odd_numbers(arr){
    for (var i = 0; i < arr.length; i++) {
        if(!(arr[i]%2==0)){
            arr.splice(i, 1);
        }
    }
    return arr;
}

function sum(array){
    var total = 0;
    for (var i = 0; i < array.length; i++) {
        total+=array[i];
    }
    return total;
}

var fib_sq = generate_fibonacci_sequence(4000000);

console.log("Before: " + fib_sq);

remove_odd_numbers(fib_sq);

console.log("After: " + fib_sq);

console.log("WTH?: " + remove_odd_numbers([1,2,3,4,5,6,7,8,9]));

出力:

Before: 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578
After: 1,2,5,8,21,34,89,144,377,610,1597,2584,6765,10946,28657,46368,121393,196418,514229,832040,2178309,3524578
WTH?: 2,4,6,8
[Finished in 0.3s]

気が狂ったりとか。何らかの理由で、すべての奇数が削除されていません。しかし、最後に見ることができるように、それは完全に機能します。何が起こっているのかわかりません。

4

5 に答える 5

8

元のコードの問題は、インデックス 0 の最初のものを削除する1と、配列がシフトされることです。今 arr[i]は2番目が含まれてい1ます。しかし、あなたはそれを乗り越えるだけです。

if here の代わりに while を使用するか、別のリストにコピーする必要があります。これはスプライシングの例です:

function remove_odd_numbers1(arr){
    for (var i = 0; i < arr.length; i++) {
        // here
        while (arr[i] % 2) {
            arr.splice(i, 1);
        }
    }
    return arr;
}

しかし、それは遅いでしょう。新しい配列を作成することをお勧めします:

function remove_odd_numbers2(arr){
    var rv = [];
    for (var i = 0; i < arr.length; i++) {
        if (! (arr[i] % 2)) {
            rv.push(arr[i]);
        }
    }
    return rv;
}

ただし、一般的に最適なアルゴリズムは、元の配列が必要ない場合は同じ配列を使用することです。これにより、余分なメモリが必要なくなります (ただし、javascript では、これは少し疑わしい値です)。

function remove_odd_numbers3(arr){
    var out = 0; 
    for (var i = 0; i < arr.length; i++) {
        if (! (arr[i] % 2)) {
            arr[out++] = arr[i]; 
        }
    }
    arr.length = out;
    return arr;
}

ただし、スプライス アルゴリズムとは異なり、これはO(n)時間内に実行されることに注意してください。

また、Array.prototype.filter() はビルトインなので悪くありません。また、新しい配列を作成するため、2 に匹敵します。

于 2013-08-19T01:56:00.027 に答える
2

これを行うための非常に簡単で高速な方法を次に示します。データを使用すると、完了するまでに 48 ミリ秒しかかかりませんでした。お役に立てれば..

function noOdds(values){
  return values.filter(function (num) {
    return num % 2 === 0;
  });
}
于 2015-06-19T18:38:10.067 に答える