0

1つのパラメーター(3桁の整数)が渡された短いPerl prgを作成したいのですが、どのリストのメンバーであるかに応じて、対応するリストの番号が返されます。どうすればこれを達成できますか?また、数値の範囲を要素としてリストに入れる方法はありますか?

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

Three-digit numbers require an array of only one thousand elements. I suggest unpacking the data into an array and simply indexing that array with the passed parameter.

This program shows the idea. It expects the three-digit number on the command line.

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";

output

Value 832 appears in group 2

Update

Alternatively you could check whether the passed parameter matches each range as you process it.

The output is identical to the previous solution.

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

次のURLを参照してください。

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

数値の範囲を持つという問題はさておき、この問題を解決する簡単な方法は、数値のハッシュとそれらが属するグループを作成することです。

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

次に、エラーチェックを追加して、1つの番号が2つのグループに表示されないことを確認できます。

于 2012-07-03T20:17:18.530 に答える
0

おそらく、List ::MoreUtilsの関数(など)を使用することをお勧めしますany

于 2012-07-03T20:22:04.853 に答える
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 に答える