7

我正在尝试在 JavaScript 中创建一个函数,给定一个字符串将返回一个包含所有可能字母组合的数组,每个字母最多使用一次,从最短的开始。例如,对于字符串 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 回答
2

这是使用循环,正如你所期望的最简单的方法..祝你好运

        function mixString() {
            var inputy = document.getElementById("mixValue").value
            var result = document.getElementById("mix-result")
            result.innerHTML=""

            
            for (var i = 0 ; i < inputy.length; i++) {
               
                for (var b = 0 ; b < inputy.length; b++) {
                    
                    if (i == b) {
                        
                        result.innerHTML += inputy.charAt(i) + ","
                    }
                    else
                    {
                        result.innerHTML += inputy.charAt(i) + inputy.charAt(b) + ","
                    }
                    
                }

            }
        }
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    
    <div class="container">
        <div class="panel panel-default">
            <div class="panel-heading">JavaScript string combination
</div>
            <div class="panel-body">
                <input id="mixValue" class="form-control" />
                <input type="button" onclick="mixString()" value="click" />
                <div id="mix-result"></div>
            </div>
        </div>
    </div>

于 2017-08-09T09:18:56.127 回答
1
function combinations(var1) {

    var temp;

    for (var i = 0; i < var1.length; i++) {
        var2 = "";

        temp = i;

        while (temp < var1.length) {

            var2 = var2.concat(var1.charAt(temp));
            // console.log(var2)
            if (i == var1.length - 1)
                document.getElementById('result').innerHTML += var2;

            else
                document.getElementById('result').innerHTML += var2 + ',';
            temp++;
        }
    }
}
于 2019-12-01T16:01:10.793 回答
0

您可以通过使用或不使用给定键处的字符来采用迭代和递归方法。

function combine(string) {
    function iter(i, temp) {
        if (i >= string.length) {
            result.push(temp);
            return;
        }
        iter(i + 1, temp + string[i]);
        iter(i + 1, temp);
    }

    var result = [];
    iter(0, '');
    return result;
}

console.log(combine('jump'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

于 2018-02-19T15:00:56.220 回答
0

截至 2019 年 7 月 29 日,公认的解决方案允许在数组中返回重复的字符串。以下调整通过向推送添加条件来解决这个小问题。

            // however, we don't want duplicates so...
            if (!result.includes(next)) {
                result.push(next);    
            }
于 2019-07-29T17:00:49.767 回答
0

生成器允许非常干净的实现:

// Very short generator produces all possible strings composed of the given chars!
let allStrings = function*(chars) {
  yield '';
  for (let prefix of allStrings(chars)) for (let c of chars) yield `${prefix}${c}`;
};

// Render the first 1000 strings
document.body.style.fontFamily = 'monospace';
let count = 0;
for (let str of allStrings('abcd')) {
  let div = document.createElement('div');
  div.innerHTML = `${(count + 1).toString().padStart(4, '0')}: ${str}`;
  document.body.appendChild(div);
  if (count++ > 1000) break;
}

请注意,第一个结果allStrings是空字符串。如果避免这种情况至关重要,可以使用以下实现:

let allStrings = function*(chars, includeEmpty=false) {
  if (includeEmpty) yield '';
  for (let prefix of allStrings(chars, true)) for (let c of chars) yield `${prefix}${c}`;
};
于 2020-07-22T16:03:55.000 回答
-1

//字符串的所有组合 // dog => d,do,dog,og,g

function combinationString(){
    let str = 'dog';
    let combinationArray = [];

    for(i=0; i< str.length; i++){
        for(j=i+1; j<=str.length; j++){
            combinationArray.push(str.slice(i,j));
        }
    }
    console.log("Combination ", combinationArray);
}
combinationString()
于 2021-05-29T07:24:17.483 回答