0

我想写一个简短的 Perl prg,它有 1 个参数(一个 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
4

6 回答 6

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;
于 2012-07-03T21:02:40.313 回答
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

于 2012-07-03T20:20:12.230 回答
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;
于 2012-07-03T20:25:10.600 回答
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';
于 2012-07-03T22:09:30.347 回答
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...

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

于 2012-07-03T20:17:18.530 回答
0

您可能想要使用List::MoreUtils中的函数,例如any.

于 2012-07-03T20:22:04.853 回答