【问题标题】:get all combinations for a string获取字符串的所有组合
【发布时间】:2012-08-16 10:19:35
【问题描述】:

我正在尝试在 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。数组中最短的也很重要。

这不是家庭作业。这是一个解决“熄灯”类型游戏的程序。

【问题讨论】:

    标签: javascript combinations


    【解决方案1】:

    这是一个我认为很容易理解的递归解决方案。

    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('')
    }))

    【讨论】:

    • 这比其他函数提供了更多可能的结果,我认为这应该是大多数可能答案的正确答案。
    【解决方案2】:

    您可以使用一个讨厌的技巧并增加一个计数器并将其二进制表示用作标志:

    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'));

    Jsbin

    【讨论】:

    • 这确实很快,但不包括与原始字符串长度相同的组合。例如,“ABC”也应该将“CBA”作为结果之一。是否对此进行了修改以包括这些组合?
    • @sebastian 您正在寻找所有可能的排列,而不是组合
    【解决方案3】:

    这就是我最终使用的。

    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;
    }
    

    【讨论】:

    • 但是,我发现您的解决方案不符合 get all combinations 的意图。例如,doing combinations('dog') 给出了[ 'd', 'o', 'g', 'do', 'dg', 'og', 'dog' ],这不是所有组合god, go, gd 不见了。一个潜在的解决方案可能是将结果分成两部分,reverse() 后半部分,然后重新附加到原始结果以适应回文字符串的用例。
    • 正如我在原始问题中所说,我不希望包含排列。在我的用例中,“狗”和“上帝”会得到相同的结果,因此是多余的。
    【解决方案4】:

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

            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>

    【讨论】:

      【解决方案5】:
      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++;
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

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

        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; }

        【讨论】:

          【解决方案7】:

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

                      // however, we don't want duplicates so...
                      if (!result.includes(next)) {
                          result.push(next);    
                      }
          

          【讨论】:

            【解决方案8】:

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

            // 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}`;
            };
            

            【讨论】:

              【解决方案9】:

              //字符串的所有组合 // 狗 => 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()
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-08-17
                • 1970-01-01
                • 1970-01-01
                • 2020-08-21
                • 1970-01-01
                相关资源
                最近更新 更多