web-dev-qa-db-ja.com

文字列のすべての順列を再帰的に出力します(Javascript)

私は他の言語でこの質問のバージョンを見てきましたが、JSでは見ていません。

これを1つの関数で再帰的に行うことは可能ですか?

文字列の最初の要素を取得し、それを文字列の残りの再帰の各ソリューションに追加する必要があることを理解しています。論理的には、再帰を実行する方法を理解しています。再帰的なソリューションのそれぞれに最初の文字を追加する方法がわかりません

var myString = "xyz";

function printPermut(inputString){
    var outputString;
    if(inputString.length === 0){
        return inputString;
    }
    if(inputString.length === 1){
        return inputString;
    }
    else{
       for(int i = 0; i<inputString.length(); i++){
           //something here like: 
           //outputString = outputString.concat(printPermut(inputString.slice(1))??
           //maybe store each unique permutation to an array or something?
       } 
    }
}
26
singmotor

文字列のすべての順列を配列として返す関数を書きましょう。グローバル変数は必要ないので、順列を返すことが重要です。

function permut(string) {
    if (string.length < 2) return string; // This is our break condition

    var permutations = []; // This array will hold our permutations

    for (var i=0; i<string.length; i++) {
        var char = string[i];

        // Cause we don't want any duplicates:
        if (string.indexOf(char) != i) // if char was used already
            continue;           // skip it this time

        var remainingString = string.slice(0,i) + string.slice(i+1,string.length); //Note: you can concat Strings via '+' in JS

        for (var subPermutation of permut(remainingString))
            permutations.Push(char + subPermutation)

    }
    return permutations;
}

それらを印刷するには、後で配列を繰り返します:

var myString = "xyz";
permutations = permut(myString);
for (permutation of permutations)
    print(permutation) //Use the output method of your choice

ご質問にお答えできることを願っています。

57
Syntac

順列の問題は死ぬまで研究されてきました。 ヒープのアルゴリズム は、よく知られたソリューションの1つです。これは、ジェネレーターを使用したJSのバージョンです。

function *permute(a, n = a.length) {
  if (n <= 1) yield a.slice();
  else for (let i = 0; i < n; i++) {
    yield *permute(a, n - 1);
    const j = n % 2 ? 0 : i;
    [a[n-1], a[j]] = [a[j], a[n-1]];
  }
}

console.log(Array.from(permute("abcabad".split('')))
.map(perm => perm.join(''))
.filter((el, idx, self) => (self.indexOf(el) === idx)));

permuteは、文字列ではなく配列を取得して生成するように設計されているため、呼び出す前に文字列を文字に分割し、結果を出力する前に文字を文字列に貼り付けます。

40
user663031

再帰関数を使用して、文字列を反復処理します

    

    function getPermutations(string) {
      var results = [];

      if (string.length === 1) 
      {
        results.Push(string);
        return results;
      }

      for (var i = 0; i < string.length; i++) 
      {
        var firstChar = string[i];
        var otherChar = string.substring(0, i) + string.substring(i + 1);
        var otherPermutations = getPermutations(otherChar);
        
        for (var j = 0; j < otherPermutations.length; j++) {
          results.Push(firstChar + otherPermutations[j]);
        }
      }
      return results;
    }
    
    var permutation = getPermutations('YES').filter((el, idx, self) => (self.indexOf(el) === idx));
    console.log("Total permutation: "+permutation.length);
    console.log(permutation);
3
Nikhil Mahirrao

セミオフトピック:

与えられた文字列のランダム置換はrndpermと同じくらい簡単です:

_i = document.getElementById("Word");
b = document.getElementById("butt");

rndperm = (z) => {
  return z.split("").sort(() => ((Math.random() * 3) >> 0) - 1).join("")
}

function scramble() {
  i.value = rndperm(i.value);
}

var z;

function sci() {
  if (z != undefined) {
    clearInterval(z);
    b.innerText = "Scramble";
    z=undefined;
  } else {
    z = setInterval(scramble, 100);
    b.innerText = "Running...";
  }
}_
<center><input id="Word" value="HelloWorld"></input><button id="butt" onclick=sci()>Scramble</button></center>
0
Zibri