(处理搜索算法)我想用16位字中设置的两个位迭代可能的匹配。对于当前过于复杂的解决方案来说,这似乎是一个愚蠢的问题。
迭代应该返回(十进制)3,5,6,9,10,12,17 ......
问题的正确用法是什么?位掩码套住? 这有什么聪明的功能吗?
当前代码 - 现已更新: (按照目前的情况,我猜有更简单的方法。)
<?php
function biterate($numBits=8, $setBits=2, $maxval=null) {
//init
if(is_null($maxval)) $maxval = (pow(2,$setBits)-1) * pow(2,$numBits - $setBits);
$err = 0;
header('content-type:text/plain');
echo '-- ' . $setBits . ' of ' . $numBits . " --\r\n";
$result = str_pad('', $numBits - $setBits, '0') . str_pad('', $setBits, '1');
do {
$err++;
if($err > 200) die('bad code');
//echo and calc next val.
echo $result . ' : ' . bindec($result) . "\r\n";
//count set bits and search for '01' to be replaced with '10'. From LSB.
$bitDivend = '';
$hit = false;
for($i=$numBits;$i>0;$i--) {
if(substr($result,$i-2,2) == '01') {
$hit = true;
//do the replacement and replace the lower part with bitDivend.
$result = substr($result, 0, $i-2) . '10';
$result .= str_pad('',$numBits - $i - strlen($bitDivend),'0');
$result .= $bitDivend;
//exit loop
$i = 0;
}
if($result[$i-1] == '1') $bitDivend .= '1';
}
} while($hit && bindec($result) <= $maxval);
}
biterate(8,2);
biterate(8,7);
biterate();
答案 0 :(得分:1)
如果您只想要设置2位的所有16位整数,则应使用以下代码:
<?php
for($i=1;$i<16;$i++)
{
for($j=0;$j<$i;$j++)
{
echo (1<<$i)|(1<<$j) , "\r\n";
}
}
?>
如果您查看数字的位模式,您可以看到它的工作原理:
11 3
101 5
110 6
1001 9
1010 10
1100 12
10001 17
10010 18
10100 20
11000 24
等。对于外部循环的每次迭代,您只需向左移动一个最高位(另一个幂为2),在内部循环内,从最低有效位(1)迭代到最右边的1个位置重要的一点。
如果你想将它概括为支持任意数量的位和位,你可以使用递归来扩展上述算法:
<?php
function biterate_recursive($numBits=8, $setBits=2, $initialValue=0, $maxval=null) {
for($i=$setBits-1;$i<$numBits;$i++)
{
if(!is_null($maxval) && ($initialValue|(1<<$i)) > $maxval)
break;
if($setBits==1)
echo $initialValue|(1<<$i) , "\r\n";
else
biterate_recursive($i, $setBits-1, $initialValue|(1<<$i), $maxval);
}
}
biterate_recursive(16, 2);
?>
您还可以将问题视为仅选择组合,即C(16,2)从集合0-15中选择2个数字a,b,然后计算(1<<a)|(1<<b)
。但是,如果要按顺序获取数字,则必须小心选择组合算法。