繁体   English   中英

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

[英]In Perl, how can I check if a number is an element of an array?

我想写一个简短的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

使用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";
       } 

请参阅以下URL:

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

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

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

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;

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

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...

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

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

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

#!/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;

对组的数量进行硬编码或为每个组创建独立的数组并不是一个好主意。

#!/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';

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM