如何获得两位设置的数字系列,16位int?

时间:2017-05-04 07:26:02

标签: php bit-manipulation

(处理搜索算法)我想用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();

1 个答案:

答案 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)。但是,如果要按顺序获取数字,则必须小心选择组合算法。