我试图了解如何使用双循环查找字符串的所有组合,但我遇到的解决方案对我的理解来说太复杂了。该函数完成了我的需要,但我已经初步了解设置单循环或双循环。
我希望能够逐步解释正在发生的事情但是针对具体问题:什么功能是" 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;
输出:a ag ae g ge e
答案 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上找到关于二元的很多解释