我正在尝试为给定位宽内的1对生成所有可能的组合。
假设比特宽度为6,即数字32.这就是我想要生成的内容:
000000
000011
000110
001100
001111
011000
011011
011110
110000
110011
110110
111100
111111
如果我有变量:
var a = 1,
b = 2;
num = a | b;
并创建一个我将循环width - 1
次的循环,并且在我移动a << 1
和b << 1
的位置,我将获得一对的所有组合。在那之后,我几乎陷入困境。
请有人提供一些帮助。
更新:工作示例
基于Barmar的数学方法,这是我设法实现的目标
var arr = [],
arrBits = [];
function getCombs(pairs, startIdx) {
var i, j, val = 0, tmpVal, idx;
if (startIdx + 2 < pairs) {
startIdx = arr.length - 1;
pairs -= 1;
}
if (pairs < 2) {
return;
}
for (i = 0; i < pairs-1; i++) {
idx = startIdx - (i * 2);
val += arr[idx];
}
for (j = 0; j < idx - 1; j++) {
arrBits.push((val + arr[j]).toString(2));
}
getCombs(pairs, startIdx-1);
}
(function initArr(bits) {
var i, val, pairs, startIdx;
for (i = 1; i < bits; i++) {
val = i == 1 ? 3 : val * 2;
arr.push(val);
arrBits.push(val.toString(2));
}
pairs = Math.floor(bits / 2);
startIdx = arr.length - 1;
getCombs(pairs, startIdx);
console.log(arrBits);
}(9));
关于JSFiddle的工作示例
http://jsfiddle.net/zywc5/
答案 0 :(得分:3)
只有一对1的数字是序列3,6,12,24,48 ......;他们从3开始,每次只加倍。
两对1的数字是12 + 3,24 + 3,24 + 6,48 + 3,48 + 6,48 + 12,...;这些是从12 +原始序列开始直到n / 4的上述序列。
三对1的数字是48 + 12 + 3,96 + 12 + 3,96 + 24 + 3,96 + 24 + 6,......
这些中的每一个之间的关系表明利用原始倍增序列的递归算法。我现在没有时间写它,但我认为这应该让你去。
答案 1 :(得分:0)
如果位宽不是那么大,那么在循环中为0到31之间的所有数字创建位表示会更好,并且只是忽略位中具有奇数个“1”的位表示表示。
答案 2 :(得分:0)
也许以二进制方式正常开始计数并将11的全部1替换为:
n = 5
n = n.toString(2) //= "101"
n = n.replace(/1/g, "11") //= "11011"
n = parseInt(n, 2) //= 27
所以你会得到:
0 -> 0
1 -> 11
10 -> 110
11 -> 1111
100 -> 1100
101 -> 11011
110 -> 11110
111 -> 111111
等等。您必须在左侧计数最多31个左右,并拒绝右侧超过6位的数据。
答案 3 :(得分:0)
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var j=0;j<arr.length;j++){
var k=j;
if(getNum1(arr[j])%2===1){
arr[j]+=1;
}else{
if(i<len-1){
arr.splice(j+1,0,arr[j]+1);
j++;
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.join('<br />'));
或者您可能更喜欢http://jsfiddle.net/SBH6R/1/。它更简单,但是你必须sort()
数组:
var len=6,
arr=[''];
for(var i=0;i<len;i++){
for(var k=0,l=arr.length;k<l;k++){
if(getNum1(arr[k])%2===1){
arr[k]+=1;
}else{
if(i<len-1){
arr.push(arr[k]+1);
}
arr[k]+=0;
}
}
}
function getNum1(str){
var n=0;
for(var i=str.length-1;i>=0;i--){
if(str.substr(i,1)==='1'){n++;}
else{break;}
}
return n;
}
document.write(arr.sort().join('<br />'));
如果要比较效果,请参阅http://jsperf.com/generate-all-combinations-for-pair-of-bits-set-to-1。似乎最快的代码是Chrome上的第一个代码,但是Firefox上的第二个代码。
答案 4 :(得分:0)
你也可以通过比特琐事来做到这一点。如果最低的两位为零,我们需要设置它们,这相当于增加3.否则,我们需要用它的最高位和它左边的1位替换最低的1块。这可以按如下方式完成,其中x
是当前组合:
x3 = x + 3;
return (((x ^ x3) - 2) >> 2) + x3;