сопоставление регулярных выражений, я думаю, - PullRequest
0 голосов
/ 21 октября 2011

Сначала извините, если бы мне пришлось добавить это к моему более раннему вопросу сегодня , но теперь у меня есть приведенный ниже код, и у меня возникают проблемы с получением вещей, которые можно добавить до 100 ...

use strict;
use warnings;

my @arr = map {int( rand(49) + 1) } ( 1..100 ); # build an array of 100 random numbers between 1 and 49

my @count2;

foreach my $i (1..49) {

my @count = join(',', @arr) =~ m/,$i,/g; #  ???
my $count1 = scalar(@count); # I want this $count1 to be the number of times each of the numbers($i) was found within the string/array.

#  push(@count2, $count1 ." times for ". $i); # pushing a "number then text and a number / scalar, string, scalar" to an array.
 push(@count2, [$count1, $i]); 
}

 #sort @count2 and print the top 7
my @sorted = sort { $b->[0] <=> $a->[0] } @count2;
my $sum = 0;
foreach my $i (0..$#sorted) {  # (0..6)

 printf "%d times for %d\n", $sorted[$i][0], $sorted[$i][1];
  $sum += $sorted[$i][0]; # try to add up/sum all numbers in the first coloum to make sure they == 100

}

print "Generated $sum random numbers.\n"; # doesn't add up to 100, I think it is because of the regex and because the first number doesn't have a "," in front of it
# seem to be always 96 or 97, 93...

Ответы [ 3 ]

1 голос
/ 21 октября 2011

Замените эти две строки:

my @count = join(',', @arr) =~ m/,$i,/g; #  ???
my $count1 = scalar(@count); # I want this $count1 to be the number of times each of the numbers($i) was found within the string/array.

с этим:

my $count1 = grep { $i == $_ } @arr;

grep вернет список элементов, для которых только выражение в {} будет иметь значение true. Это менее подвержено ошибкам и намного более эффективно, чем join использование всего массива и использование регулярных выражений. Также обратите внимание, что scalar не требуется, поскольку переменная $count1 является скалярной, поэтому perl вернет результат grep в скалярном контексте.

Вы также можете избавиться от этой строки:

push(@count2, $count1 ." times for ". $i); # pushing a "number then text and a number / scalar, string, scalar" to an array.

поскольку вы уже печатаете ту же информацию в своем последнем цикле foreach.

0 голосов
/ 21 октября 2011
#!/usr/bin/perl

use strict; use warnings;
use YAML;

my @arr;
$#arr = 99;

my %counts;

for my $i (0 .. 99) {
    my $n = int(rand(49) + 1);
    $arr[ $i ] = $n;
    ++$counts{ $n };
}

my @result = map  [$_, $counts{$_}],
             sort {$counts{$a} <=> $counts{$b} }
             keys %counts;

my $sum;
$sum += $_->[1] for @result;

print "Number of draws: $sum\n";
0 голосов
/ 21 октября 2011

Вероятно, вы можете повторно использовать хорошо протестированный код из List :: MoreUtils .

use List::MoreUtils qw/ indexes /;
...
foreach my $i (1..49) {
    my @indexes = indexes { $_ == $i } @arr;
    my $count1 = scalar( @indexes );
    push( @count2, [ $count1, $i ] ); 
}

Если вам не нужны предупреждения в цикле суммирования, я бы рекомендовал использовать сумму из Список: Util .

use List::Util qw/ sum /;
...
my $sum = sum map { $_->[0] } @sorted;

Если вы настаиваете на цикле, перепишите его как:

foreach my $i ( @sorted ) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...