7

JavaScript で関数を作成しようとしています。これは、指定された文字列が文字のすべての可能な組み合わせの配列を返し、それぞれが最も短いものから始めて、最大で 1 回使用されます。たとえば、文字列 ABC の場合、次のように返されます。

A
B
C
AB
AC
ABC

次のようにループを使用できます。

for(i=0; i<string.length; i++) {
   //add string[i]
}
for(i=0; i<string.length; i++) {
    for(a=i; a<string.length; a++) {
            //add string[i]+string[a]
    }
}
for(i=0; i<string.length; i++) {
    for(a=i; a<string.length; a++) {
        for(b=a; b<string.length; b++) {
            //add string[i]+string[a]+string[b]
        }
    }
}

しかし、文字列の長さがわからないので、使用するループの数がわかりません。

何か案は?

編集:順列を求めているわけではありません.abcとacbの両方が返されるべきではありません。また、配列の最初にある最短のものも重要です。

これは宿題ではありません。「ライトアウト」タイプのゲームを解決するためのプログラムです。

4

9 に答える 9

9

これは非常に理解しやすいと思う再帰​​的なソリューションです。

var tree = function(leafs) {
  var branches = [];
  if (leafs.length == 1) return leafs;
  for (var k in leafs) {
    var leaf = leafs[k];
    tree(leafs.join('').replace(leaf, '').split('')).concat("").map(function(subtree) {
      branches.push([leaf].concat(subtree));
    });
  }
  return branches;
};
console.log(tree("abc".split('')).map(function(str) {
  return str.join('')
}))

于 2012-08-21T05:36:38.463 に答える
6

厄介なトリックを使用してカウンターを増やし、そのバイナリ表現をフラグとして使用できます。

function combine(str){
   const result = [];
   for(let i = 1; i < Math.pow(2, str.length) - 1; i++)
      result.push([...str].filter((_, pos) => (i >> pos) & 1).join(""));
  return result;
}
console.log(combine('abcd'));

ジャスビン

于 2018-02-19T14:52:13.930 に答える
4

これが私が最終的に使用したものです。

var combinations = function (string)
{
    var result = [];

    var loop = function (start,depth,prefix)
    {
        for(var i=start; i<string.length; i++)
        {
            var next = prefix+string[i];
            if (depth > 0)
                loop(i+1,depth-1,next);
            else
                result.push(next);
        }
    }

    for(var i=0; i<string.length; i++)
    {
        loop(0,i,'');
    }

    return result;
}
于 2013-05-19T20:16:45.893 に答える