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