2017-01-20 11 views
0

なぜ私のコードがすべての順列を2回押しているのか混乱しています。助けてください。私は、ヒープのアルゴリズムを使用しています:私のコードがすべての順列を2回押すのはなぜですか?

var regex = /(.)\1+/g; 

function permAlone(str) { 
    var newArray = str.split(''); 
    var n = newArray.length; 
    var permutations = []; 
    var tmp; 

    function swap(index1, index2) { 
    tmp = newArray[index1]; 
    newArray[index1] = newArray[index2]; 
    newArray[index2] = tmp; 
    } 

    function generate(n, newArray) { 
    if (n === 1) { 
     permutations.push(newArray.join('')); 
    } else { 
     for(var i = 0; i<n-1; i++) { 
     generate(n-1, newArray); 
     swap(n % 2 ? 0 : i, n-1); 
     permutations.push(newArray.join('')); 
     } 

     generate(n-1, newArray); 
    }  
    } 

    generate(n, newArray); 
    return permutations; 
}  

permAlone('aab'); 

返される配列は次のとおりです。

["aab", "aab", "aab", "baa", "baa", "aba", "aba", "aba", "baa", "baa"] 

あなたが見ることができるように、順列は各事を意図したよりも多くの回登場しています。すべてのヘルプは

+0

重複に加えて、 'generate(n-1、newArray);'の2番目の呼び出しは不要です。これはループの最後の最後の繰り返しと同じことを行うだけです。 – samgak

+0

文字列が 'aab'なので、2つの' aab'と2つの 'aba'(2つの' a'があるので)またはただ1つを期待していますか? –

+0

...なぜ正規表現..? – Redu

答えて

1

コードは少し複雑だ素晴らしいことだし、それは再帰与えられた追跡するのは難しいのですが、あなたが望むすべてが唯一の一意の値を持つ配列がある場合、あなたは、単に結果の配列に次のコードを適用することができます。

function stripDuplicates(input) { 
    if (!input || typeof(input) !== 'object' || !('length' in input)) { 
     throw new Error('input argument is not array.'); 
    } 

    var newArray = []; 
    for (var i = 0; i < input.length; i++) { 
     if (newArray.indexOf(input[i]) === -1) { 
      newArray.push(input[i]); 
     } 
    } 

    return newArray; 
} 

これは、命令的ではなく機能的に行うこともできますが、実際は最適化の問題よりも優先されます。

Bálintは、結果をSetに変換し、SetArrayに戻すと、自動的に重複を取り除くことができると指摘しています。ただし、SetはJavascriptの比較的新しいアフォーダンスであり、ES6以前の環境では機能しないことに注意してください。

+0

または、それらをセットに入れて配列に変換するだけです。誰も好きではないようです。 –

+0

@Bálintまたはそれも!あなた自身の答えとしてそれを自由に追加してください。それは素晴らしい考えです。この利点は、後で他の要件がある場合でも、ループ内の他の操作を行うことができることです。可能な限り下位互換性のある私の答えを作成しようとしているため、SetオブジェクトはES6 +にしか存在しないため、私はそれをしないことにしました。 – furkle

+0

Nah、あなたはちょうどそれを追加する必要があります。今は時間がありません。 –

0

あなたはへの呼び出しがあります:あなたのforループの内部

permutations.push(newArray.join('')); 

を。それはそこにはないはずです。もちろん、文字が重複している文字列を並べ替えると、うまく表示されません。たとえば、文字列 "aa"を並べ替えると、このアルゴリズム "aa"と "aa"の2つのエントリが得られます。ヒープのアルゴリズムはダプルを削除しようとしません、それは文字列内の各要素を一意であるとみなします。明らかに、あなたが気にしていることがあれば、それを削除することは自明です。

関連する問題