Вот некоторые PHP-код для вас, но, пожалуйста, обратите внимание, что это очень неэффективно. Я использовал этот алгоритм, потому что:
- Это явное и использует слова, а не математические ухищрения, чтобы получить работу, и
- работы в ситуациях, когда вы не можете предположить, лежащий в основе реализации 2s дополнения, но все еще хотят «думать» таким образом. (попробуйте «хранение» битмаски в PHP и думать, что они будут работать в JavaScript)
Пожалуйста, прочтите комментарии и осуществлять @Paebbels решение. Разница в производительности почти 7x, поэтому на самом деле это использовать, если она не будет использоваться очень часто.
Он использует 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";
}
}
Выход:
14 является одним
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));
Выход:
Массив ( [0] => Три 1 => Четыре [2] => Семь )
Извините, но это решение потребляет массу памяти и циклы процессора для работы простых битовых сдвигов и бит-сравнений. – Paebbels
_ Массы памяти_? Не так уж плохо для 32-битной целочисленной маски. Если у вас нет требований в режиме реального времени (.. в PHP ..) или вы неоднократно вызываете это, то это решение подходит. В противном случае, я уверен, что люди найдут ваш ответ полезным. –
Мое решение: 3 слова á 4 байта = 12 байтов {m, j, i}, у него нет инструкций по вызову. - Ваше решение преобразует маску из int в строку; использует базовое преобразование, основанное на двойных значениях (строка для double, base convert, to string conversion); после этого используется строковая операция (str_split) и, наконец, строковая обратная операция. Это только начальные берега ... На каждой итерации вы получаете доступ к хеш-списку и вызываете функцию isset для простого сравнения бит. В вашем коде используется 35 инструкций по вызову. Память: каждый символ промежуточной строки хранится в 2 байтах (UTF-16) => 64 байта. – Paebbels