【问题标题】:how does it works "$_ & 1" in perlperl 中的 "$_ & 1" 是如何工作的
【发布时间】:2013-04-10 05:04:25
【问题描述】:

我是 perl 初学者,我正在阅读 grep 函数来过滤列表。我遇到了以下程序。

#!/usr/bin/perl

use strict;
use warnings;

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

# first syntax form:
my @subArray = grep { $_ & 1 } @array;

语句my @subArray = grep { $_ & 1 } @array;@array 中返回奇数。我不明白表达式($_ & 1) 是如何工作的。我在 Google 中搜索,但没有找到任何有用的链接。

  • 这是一种特殊的运算符吗?

  • EXPR 是否还有其他变体?

提前致谢。

【问题讨论】:

  • 仅供参考:这是一个非常简洁的技巧不应该在生产代码中使用,除非仅查找奇数元素的操作被基准测试为性能瓶颈。可读的实现。
  • @DVK 嗯,至于我的兴趣:这个技巧有用吗? $_||=$val
  • @loldop - ||= 运算符是完全正确的惯用 Perl,而不是 hack。但是,使用 $_ 而不是使用自文档命名的变量通常是代码编写不佳的标志,除非在非常短的 map/grep 块中使用。
  • @VARamesh,我想,你可以使用这个表达式:($_%2) 元素,在环模 2 中有余数 1
  • @DVK 感谢您提供信息。

标签: arrays perl


【解决方案1】:

$_ 是保存当前测试值的变量,& 是二元与运算符,1 只是第一个。此表达式通过逻辑 AND 将 $_1 的所有位组合在一起。所以如果值为奇数则返回 1,如果值为偶数则返回 0。

例如,假设 $_ 是 123,那么它的二进制表示是 1111011。十进制数 1 将是 00000001,因此将所有位通过 AND 组合得到

123 = 1111011
  1 = 0000001
      - AND -
      0000001 = 1

另一个例子200 & 100

200 = 11001000
100 = 01100100
      - AND --
      01000000 = 64

【讨论】:

  • 第二个例子(200 & 100),答案是64还是我的转换方式不对?
  • 你是对的,当然必须是 64。 128 是我的错误。
【解决方案2】:

正如许多人指出的那样,& 是按位与运算符。这意味着将被比较的两个数字转换为位并进行比较:

例如,3 & 1 返回1,它在 grep 中的计算结果为 true:

Num | Bits
----+-----
  3 | 1 1
& 1 | 0 1
----+-----
  1 | 0 1   <- result of 'and'ing each bit column

同样,4 &amp; 1 返回0,这是错误的:

Num | Bits
----+-------
  4 | 1 0 0
& 1 | 0 0 1
----+-------
  0 | 0 0 0  <- all zeros because no column contains 1 & 1

也就是说,过滤奇数的另一种方法是 mod 带有 2 的数字:

my @odd = grep { $_ % 2 } 1 .. 7;    # 1, 3, 5, 7

【讨论】:

    【解决方案3】:
    grep{ $_ & 1}
    

    将遍历数组的每个元素并与 1 进行逐位匹配 这意味着 grep 将匹配任何最后一个 (lsb) 位为 1 的元素。 因为只有奇数有一个 1 作为 lsb,所以这只会返回奇数

    &  is the bitwise AND 
    

    【讨论】:

      【解决方案4】:

      $_ 是当前表达式。在这种情况下,每个数组元素。

      &amp; 是二元与运算符。

      所以,简而言之,grep 将匹配任何奇数的数组元素。

      $_grep 的使用记录在 perldoc 中。 &amp;的含义也在perldoc中。

      【讨论】:

        【解决方案5】:

        $_ 是由 grep 函数设置的变量。如果没有另外指定,大多数 perl 函数都会操作 $_ 。 Grep 为@array 的每个元素调用定义的匿名子(即{ $_ &amp; 1 })并按位生成&amp;。如果结果为真值,则将其添加到结果数组中。

        【讨论】:

          猜你喜欢
          • 2011-04-16
          • 2010-10-14
          • 2013-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-16
          • 1970-01-01
          相关资源
          最近更新 更多