Nik*_*kov 9 php bit-manipulation array-map
我有一个用于位掩码的32位整数和一个32位值的数组.如何只从数组中获取哪些索引对应于位掩码中非零位的位置?
例如,假设位掩码是49152,二进制是1100000000000000.因此,我必须从数组中获取索引为14和15的元素的值.
您将需要在掩码上循环32步并测试它为'1',如果设置此位,则可以将元素复制到生成的数组中.
伪代码:
m = 0x00000001
j = 0
for i in 0 to 31 loop
if ((mask & m) = m) then // bit is set in mask
result(j++) := input(i)
end if
m := m << 1 // shift left by 1 or multiply by 2
end loop
Run Code Online (Sandbox Code Playgroud)
这里有一些 PHP 代码,但请注意,它的效率相当低。我使用这个算法是因为:
请阅读评论并实施@Paebbels 解决方案。性能差异几乎是 7 倍,因此只有在不经常使用的情况下才使用它。
它用于base_convert将以 10 为基数的整数转换为以 2 为基数的整数,将字符串拆分为字符数组,反转数组,然后迭代查找 1。
$mask = 49152; // 0xC000
// Find which positions in the mask contain a '1'
$bitArray = array_reverse(str_split(base_convert($mask, 10, 2)));
foreach($bitArray as $k => $v) {
if($v) {
echo $k . " is a one\n";
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
14是一个1
15 是一个
作为一个函数:
function extractElements($mask, array $input)
{
$output = array();
$bitArray = array_reverse(str_split(base_convert($mask, 10, 2)));
foreach($bitArray as $k => $v) {
if($v && isset($input[$k])) {
$output[] = $input[$k];
}
}
return $output;
}
$mask = 76; // 0x4C
$input = [
'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight'
];
print_r(extractElements($mask, $input));
Run Code Online (Sandbox Code Playgroud)
输出:
数组 ( [0] => 三 1 => 四 [2] => 七 )