2013-05-09 3 views
1

Учитывая целое число, я хотел бы печатать по частям в perl. Например, с учетом числа 9, я хотел бы получитьКак выполнить побитовую операцию в perl, чтобы получить счетчик самой длинной последовательности из 0s между двумя 1s

1 
0 
0 
1 

Как добиться этого. По сути, я пытаюсь сделать так, чтобы получить число самых длинных 0s между двумя 1s. Значение, если поразрядное представление числа это 1000001001, я бы хотел, чтобы эта функция perl возвращалась. 5.

Я хотел бы знать, что лучший способ кодировать это в perl. Совершенно новый для perl.

+0

Что о '1001000'? 2 или 3? – ikegami

ответ

4

С ведущими нулями:

my @bits = reverse unpack '(a)*', unpack 'B*', pack 'J>', $int; 

Без:

my @bits = reverse unpack '(a)*', sprintf '%b', $int; 

Примечания:

  • reverse используется, чтобы поместить значащий бит в $bits[0].
  • unpack '(a)*' используется для разбиения строки на отдельные биты.
  • Оба работают с целыми числами без знака.
  • Оба работают с целыми числами (в байтах), заданными perl -V:ivsize.

Если оставить его в виде строки, вы можете воспользоваться регулярными выражениями для извлечения последовательности нулей.

use List::Util qw(max); 
my $bin = sprintf '%b', $num; 
my $longest = (max map length, $bin =~ /1(0+)(?=1)/g) || 0; 

В C, вы можете сделать что-то вроде следующего, но в Perl, он может быть менее эффективным, чем ранее решения:

my $longest = 0; 
if ($num) { 
    # Cast to unsigned so that >> inserts zeroes even for neg nums. 
    $num = ~~$num; 

    # Skip zeros not between 1s. 
    $num >>= 1 while !($num & 1); 

    while (1) { 
     # Skip 1s. 
     $num >>= 1 while $num & 1; 

     last if !$num; 

     # Count 0s. 
     my $len = 0; ++$len, $num >>= 1 while !($num & 1); 

     $longest = $len if $longest < $len; 
    } 
} 
Смежные вопросы