在Perl中,如何检查数字是否是数组的元素?

时间:2012-07-03 20:01:16

标签: arrays perl list member

我想写一个简短的Perl prg,它有一个参数(一个3位整数)传递给它,并且根据它的成员,它返回相应列表的编号。我怎样才能实现这一目标,还有什么办法可以将一系列数字作为一个元素放在一个列表中吗?

 ::Returns 1,2,3,4 Depending on testNum passed
 @gp1= (829,845,851,859,864,867);
 @gp2= ("826-828","830-839","843-844","847-850","852-854","860-862","883");
 @gp3= ("855-858",861,"863","865");
 @gp4= ("877-882",884);

 if ( ($ARGV[0]>=822 && $ARGV[0] <=824) || $ARGV[0]  is membergp1)
 {  
  return 1
 }
  if ( $ARGV[0]>=826 && $ARGV[0]<=828 || $ARGV[0] is memebr of group2
    return 2
  if $ARGV[0] is memebr of group3
      return 3
  if $ARGV[0] is memebr of group4
      return 4

6 个答案:

答案 0 :(得分:1)

使用Number :: Range(必须下载)将所有列表放在范围对象中:

  use Number::Range;
  my $range= Number::Range->new("23..98,103..150");
       if ($range->inrange("110")) {
           print "In range\n";
       } else {
           print "Not in range\n";
       } 

请参阅以下网址:

http://forums.devshed.com/perl-programming-6/check-if-number-is-in-range-23-98t-574713.html https://metacpan.org/pod/Number::Range

答案 1 :(得分:1)

三位数字需要一个只有一千个元素的数组。我建议将数据解压缩到一个数组中,然后使用传递的参数简单地索引该数组。

这个程序显示了这个想法。它需要命令行上的三位数字。

use strict;
use warnings;

my @gp1=  qw(  829  845  851  859  864  867  );
my @gp2=  qw(  826-828  830-839  843-844  847-850  852-854  860-862  883  );
my @gp3=  qw(  855-858  861  863  865  );
my @gp4=  qw(  877-882  884  );

my @places;

my $n = 0;
for (\(@gp1, @gp2, @gp3, @gp4)) {
  $n++;
  for (@$_) {
    my @indices = /\d+/g;
    $places[$_] = $n for $indices[0] .. $indices[-1];
  }
}

my $val = $ARGV[0];
my $place = $places[$val];
printf "Value %s appears in %s\n", $val, $place ? "group $place" : "no group";

<强>输出

Value 832 appears in group 2

<强>更新

或者,您可以在处理时检查传递的参数是否与每个范围匹配。

输出与之前的解决方案相同。

use strict;
use warnings;

my @gp1=  qw(  829  845  851  859  864  867  );
my @gp2=  qw(  826-828  830-839  843-844  847-850  852-854  860-862  883  );
my @gp3=  qw(  855-858  861  863  865  );
my @gp4=  qw(  877-882  884  );

my $val = $ARGV[0];

my $n = 0;
for (\(@gp1, @gp2, @gp3, @gp4)) {
  $n++;
  for (@$_) {
    my @indices = /\d+/g;
    if ($val >= $indices[0] and $val <= $indices[-1]) {
      printf "Value %s appears in group %d\n", $val, $n;
      exit;
    }
  }
}

printf "Value %s appears in no group\n", $val;

答案 2 :(得分:0)

不考虑数字范围的问题,解决这个问题的一个简单方法是制作一个数字哈希以及它们所在的组。

my %num2group = (
    829 => 1,
    830 => 2,
    861 => 3,
    884 => 4,
    ...and so on...
);

然后您可以简单地查询哈希以查看数字所在的组(如果有)。

my $group = $num2group{$number};

您可以从数字列表中生成该哈希,而不是手动创建该哈希值。

$num2group{$_} = 1 for @grp1;
$num2group{$_} = 2 for @grp2;
...and so on...

这是你处理范围的地方。生成%num2group时,您会将任何范围扩展为单个哈希条目。假设这些范围不是很大,这将使得查找组有效。

for my $num (@grp1) {
    if( /^(\d+)-(\d+)$/ ) {  # range
        $num2group{$_} = 1 for $1..$2;
    }
    else {
        $num2group{$num} = 1;
    }
}

最后,不要对组号进行硬编码,而是将其放入子程序中。

sub add_to_group_hash {
    my($numbers, $group, $hash) = @_;

    for my $num (@$numbers) {
        if( /^(\d+)-(\d+)$/ ) {  # range
            $hash->{$_} = $group for $1..$2;
        }
        else {
            $hash->{$num} = $group;
        }
    }
 }

 add_to_group_hash(\@grp1, 1, \%num2group);
 add_to_group_hash(\@grp2, 2, \%num2group);
 ...and so on...

然后,您可以添加一些错误检查,以确保一个数字不会出现在两个组中。

答案 3 :(得分:0)

您可能希望使用List::MoreUtils中的函数,例如any

答案 4 :(得分:0)

您可以使用范围运算符..实现范围:

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

my @lists = (
             [829,845,851,859,864,867],
             [826 .. 828, 830 .. 839, 843 .. 844, 847 .. 850, 852 .. 854, 860 .. 862, 883],
             [855 .. 858, 861, 863, 865],
             [877 .. 882, 884]
            );

say join ' ',
         "In list(s):",
         grep { grep $_ == $ARGV[0], @{ $lists[$_ - 1] }} 1 .. @lists;

答案 5 :(得分:0)

硬编码组数或为每个组创建独立数组不是一个好主意。

#!/usr/bin/env perl

use strict; use warnings;
use feature 'say';
use List::MoreUtils qw( first_index );

my @groups = (
    [829, 845, 851, 859, 864, 867 ],
    [
        826 .. 828,
        830 .. 839,
        843 .. 844,
        847 .. 850,
        852 .. 854,
        860 .. 862,
        883,
    ],
    [ 855 .. 858, 861, 863, 865 ],
    [ 877 .. 882, 884 ],
);

my ($candidate) = @ARGV;

my $group = first_index {
    (-1 < first_index { $candidate == $_ } @$_)
} @groups;

say $group > -1 ? $group : 'not found';