字符串双循环(JavaScript)

时间:2017-08-02 14:31:23

标签: javascript loops combinations

我试图了解如何使用双循环查找字符串的所有组合,但我遇到的解决方案对我的理解来说太复杂了。该函数完成了我的需要,但我已经初步了解设置单循环或双循环。

我希望能够逐步解释正在发生的事情但是针对具体问题:什么功能是" i< Math.pow(2,n)-1 ","((i&(1 << j))== 1 << j)"和" var comb ='&#39 ;; (临时存储?)"服务?



subsets = function(str) { 
      var n = str.length;
      for (var i=1; i< Math.pow(2,n)-1; i++) {
        var comb = '';
        
        for (var j=0; j<n; j++) {
          var use = ((i & (1 << j)) == 1 << j);
          if(use)comb+=str.charAt(j);
        }
        console.log(comb);
      }
    }
    
    subsets("age");
&#13;
&#13;
&#13;

输出:a ag ae g ge e

4 个答案:

答案 0 :(得分:3)

要获得字符串的随机组合,我们可以设置一个布尔数组,存储是否应该显示其中一个字符,例如:

"a","g","e"
[true,false,true]
=>"ae"

所以可能的变化数量是

2 /*true/false*/ ** str.length 

用旧式写的:

Math.pow(2,str.length)

所以主循环迭代所有可能的组合,除了第一个(因为我从1开始),因为那将是一个空字符串,最后一个(-1)将是&#34; age&#34 ;。虽然我是一个简单计数的整数,但我们也可以想象它是一个布尔数组(在按位视图中):

integer
bits
boolean array

1
001
[false,false,true]

2
010
[false,true,false]

3
011
[false,true,true]

4
100
[true,false,false]

... 
6 < 2 ** 3 -1
110
[true,true,false]

现在是内循环:

for (var j=0; j<n; j++) {
  var use = ((i & (1 << j)) == 1 << j);
  if(use)comb+=str.charAt(j);
}

只需查看我们的字母并检查布尔标志是否为真,所以在i = 5时,布尔数组将是:

[true,false,true]//101

并转换为

"ae"

它看起来如何:

真实的(&#34; a&#34;):

 101 // i
&001 //1<<j where j is 0
=001
===
 001 //1<<j

假的(&#34; g&#34;):

 101
&010 //1<<j where j is 1
=000
!==
010 //1<<j

真实的(&#34; e&#34;):

 101 // i
&100 //1<<j where j is 2
=100
===
 100 //1<<j

因此它检查布尔数组(i)是否在js索引处为真,如果是,则添加该字母。 BTW更短:

 if(i & (1<<j))

答案 1 :(得分:2)

var i=1; i< Math.pow(2,n)-1; i++

Math.pow(2,n) - 1所说的是运行此循环直到(2 ^ n)-1,其中&#39; n&#39;是字符串的长度。因此,对于输入&#39; age&#39;,第一个for循环将运行,而i从1开始并且每个循环递增1,小于(2 ^ 3)-1。因此,第一个循环将运行6次。

var comb = ''

正是您的想法 - 存储用于记录的内容,因为for循环可以完成它们的工作!

关于(i & (1 << j)) == 1 << j),我们进入的地方Bitwise operators!不幸的是,我几乎不能理解这些解释它们:(

答案 2 :(得分:1)

Math.pow是一个幂函数。第一个参数是基数,第二个参数是指数,因此Math.pow(2,n)相当于2 ^ n。在循环中,i< Math.pow(2,n)表示for循环的边界是,而i小于2 ^ n,其中n是字符串长度。

var comb = '';正在初始化一个空字符串。此字符串稍后在循环中连接,因此此声明用于建立用于连接的变量。

答案 3 :(得分:1)

这是基于二进制(0/1)的代码 operators in javascript 解释&lt;&lt;它是一个“通过向右插入零来向左移动b位的二进制表示” 和&amp; :对于每个位位置返回1,两个操作数的相应位为1。

如果你有一些问题要解决代码问题,请用简单的例子一步一步地在纸上试试。 尝试示例str =“a”,尝试“开启”......

For "a" the beginning is 
 var n = str.length; // 1
for (var i=1; i< Math.pow(2,n)-1; i++) { // for i=1;i<2^1-1 =2-1=1;i++
var comb = '';
for (var j=0; j<n; j++) {//for j=0;j<1;j++
var use = ((i & (1 << j)) == 1 << j);// use = 1 & (1 << 0 insert 0 times 0)) == 1 << 0= (1 & 1)== 1=true (1==1)
if(use)comb+=str.charAt(j);//comb='' + a.charAt(0)=  comb= '' + "a"='a'

......你继续循环。

binary是一种用0/1写入数字的方法:

示例00101(二进制)

U有5位数,然后1rst 0 = 0 * 2 ^(右边1位数)= 0 * 2 ^ 4 = 0

  

然后00101(二进制)= 0 * 2 ^ 4 + 0 * 2 ^ 3 + 1 * 2 ^ 2 + 0 * 2 ^ 1 + 1 * 2 ^ 0

               = 0     + 0     + 1*4   + 0     + 1*1

               = 5 in current using (decimal)

你在Google上找到关于二元的很多解释