「コネラック」からの発言を出発点として、解決したと思います。確かに、問題は決して減少しないリストでした。私は参照配列に精通していないので、ちょっと迷いましたが、どういうわけかコードを読んで、予想される動作の類似性を見つけようとしました。
したがって、@ reservedaという別の配列を作成し、次のように記述しました。
push @ {$reserva [$i]}, $address
それ以外の
push @addresses, $address;
これで、入力する電子メールの数に関係なく、必要なサイズのリストが表示されます。1000で試してみましたが、1秒足らずで問題ありませんでした。
だから、ここに完全なコードがあります
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my $only_index = 3; # Read from command line with $ARGV[0] or use Getopt::Long
my %blacklist = ( # Each key in this hash represents one index/day
'2' => [ 'a', 'b' ], # and has an arrayref of domains that have replied on
'3' => [ 'c' ], # that day. We look at all keys smaller than the current
); # index in each iteration and ignore all these domains
my @domains; # holds the domains we have already seen for each list
my @lists = ([]); # Holds all the lists
my %moved; # the addresses we moved to the back
my $i = 0;
my @addresses = <DATA>;
while (@addresses) {
my $address = shift @addresses;
chomp $address;
$address =~ m/@([a-zA-Z0-9\-.]*)\b/;
my $domain = $1;
# If the domain has answered, do not do it again
next if
grep { /$domain/ }
map { exists $blacklist{$_} ? @{ $blacklist{$_} } : () } (0..$i);
$i++ if (@{ $lists[$i] } == 2
|| (exists $moved{$address} && @addresses < 1));
if (exists $domains[$i]->{$domain}) {
push @addresses, $address;
$moved{$address}++;
# say "pushing $address to moved"; # debug
} else {
$domains[$i]->{$domain}++;
# send the email
# say "added $address to $i"; # debug
push @{ $lists[$i] }, $address;
}
}
# print Dumper \@lists; # Show all lists
print Dumper $lists[$only_index]; # Only show the selected list
1;
__DATA__
1@a
2@a
3@a
1@b
2@b
1@c
2@c
3@c
1@d
2@d
3@d
4@d
1@e
1@f
1@g
1@h
4@a
5@a
4@c