2013-08-11 3 views
2

Чтобы получить нечетные числа из массива, я получил этот код, но не понял один синтаксис. Код, как показано нижеПолучение нечетных чисел из массива

#!/usr/bin/perl 

use strict; 
use warnings; 

# initialize an array 
my @array = qw(3 4 5 6 7 8 9); 

my @subArray =(); 
    foreach (@array) { 
    push @subArray, $_ if $_ & 1; 
} 
print "@subArray\n"; 
# displays: 3 5 7 9 

Что "если $ _ & 1" Это работает. Но я не получил синтаксис «если $ _ & 1».

Аналогично Grep можно использовать как "мой @subArray = Grep $ _ & 1, @array;"

Пожалуйста, помогите мне понять с синтаксисом

+0

http://perldoc.perl.org/perlop.html#Bitwise-And – Sean

+0

@Sean: Спасибо за ответ. Но мне все еще не ясно. Я пошел к ссылке, но не получил. Было бы заметно, если вы объясните это – Nitesh

+0

Обязательно принимайте ответ, если вы работали для вас. – hwnd

ответ

2

Логика:
Если вы делаете операции И между нечетным числом и 1 (в двоичном виде, конечно), то полученный результат будет всегда 1.

Как это работает:
Вышеупомянутый код ищет нечетное число, выполняя побитовое И-операцию между элементом массива и номером 1. Если операция приводит к «истине», она вставляется в конечный массив (@subArray). $ _ Здесь относится к отдельному элементу исходного массива, к которому обращаются во время итерации.

Вот как работает побитовая операция И.

  1. Предположим, вы хотите определить, является ли 3 нечетным числом (двоичный код для 3 -> 0011).
  2. В соответствии с этим кодом, вы выполняете побитовое И с 1, бинарный, для которого, является 0001.
  3. операции И происходит между 0011 и 0001, и так как это побитовое, каждый бит имеет значение AND с соответствующим битом другого.
  4. Вот как это происходит,
    бинарного файла 3: 0 0 1 1
    Binary 1: 0 0 0 1
    Результат И: 0 0 0 1
  5. Как вы можете видеть, конечным результатом является 1, который также является младшим битом (первый бит начинается справа). Следовательно, выражение if $_ & 1; приводит к «истине», и число вводится в subArray посредством операции push.
4

Структура этой линии:

<statement> if <condition> 

, где <statement> - push @subArray, $_ и <condition> - $_ & 1.

Выражение $_ & 1 равно 1 или 0 в зависимости от того, установлен ли бит младшего разряда $_ или нет. Если это 1 (значение true в Perl), то выполняется push @subArray, $_; в противном случае это значение 0 (значение false в Perl), и оператор пропускается.

+0

"бит младшего разряда $ _" -> то, что бит младшего разряда – Nitesh

+0

Как он работает, чтобы найти нечетные числа из массива. Остальное синтаксис, включая «push», ясен – Nitesh

+1

@Nitesh - Это будет бит, соответствующий 2^0 в двоичном расширении '$ _'. Установленный бит эквивалентен '$ _' с нечетным значением. Это почти универсальный тест на то, является ли значение четным или нечетным. –

4

Что такое$_ & 1?

Это выражение сегрегируется низкий бит, и только номера с низким битом (нечетные номера)

  • $_ является переменным по умолчанию, в этом случае каждый элемент массива
  • & является двоичным и оператор/побитовая строка оператор (возвращает его операнды вместе по кусочкам)
  • 1 является только один

  • См perldoc perlop (Мультипликативные операторы) и bit-hacks.

В качестве альтернативы, вы можете разобрать ваш чет/нечет, используя оператор по модулю %.

Использование петли for.

my @odd; 
for (@array) { 
    push @odd, $_ if $_ % 2; 
} 

Использование map

my @odd = map { $_ % 2 ? $_ :() } @array; 

или даже array slice используя grep ..

my @odd = @array[grep { ! ($_ % 2) } 0 .. $#array]; 
3

Смысл $_ & 1 уже пояснялось выше, но в данном случае, я считаю, что было бы более удобно, если вы пишете:

my @oddArray = grep { $_ % 2 != 0 } @array;

+0

Почему '! = 0'? Я не понимаю. –

+0

@ Hynek-Pichi-Vychodil Я знаю, что это своего рода избыточность, но я просто хочу явно указать, что мы собираем нечетные числа с 'grep' в этом примере, хотя без'! = 0' он все равно делает то же самое , – Alec

+1

[Истина и ложь] (http://perldoc.perl.org/perlsyn.html # Truth-and-Falsehood) говорит, что * Число 0, строки '0' и "", пустой список() и undef являются ложными в булевом контексте. Все остальные значения верны. * '$ _% 2' оценивается только в 0 или 1, поэтому добавление'! = 0' является просто отходом во многих отношениях, включая способность мозга читателя. –

1

Почему бы не просто?

my @subArray = grep {$_ & 1} @array; 

А почему вы инициализировать массив, используя qw(3 4 5 6 7 8 9), когда вам нужно номера?

my @array = (3, 4, 5, 6, 7, 8, 9); 

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

my @subArray = grep {$_ % 2} @array; 

Разница в производительности будет незначительной, и гораздо более очевидно, что происходит.

Смежные вопросы