2012-07-21 55 views
1

我在这里有一个工作代码,它可以正常工作8或10封电子邮件,但如果你只是放20封电子邮件,它永远不会完成计算。也就是说,它不是一个无限循环,否则它永远不会计算任何东西。此外,如果您仅使用10封电子邮件,但要求它列出2个以上的电子邮件,则会发生同样的事情。是的,正如指出的那样,有一段时间(@地址),并且在那里有一个推入地址的地方,这就是原因。我试图用另一个名字替换它被推入的那个数组,但是我得到奇怪的错误,就像它从列表中选择一个电子邮件,它会抱怨说虽然严格的引用是,我不能使用它... 我明白100直到'地图'行为止的代码。在那之后,没有这么多...Perl:'半'无限循环?

如果我们看一下这个部分:

push @addresses, $address; 
    $moved{$address}++; 
#  say "pushing $address to moved"; # debug 

一会说变量$地址将不得不推,不进@addresses,因为这是数据的来源(因此指出了循环),但是移到了'移动',但是,对不起,'移动'是一个散列。你不能将一个变量推入哈希,你能吗?应该“移动”实际上是一个数组而不是散列?这是我迷路

我在想这个代替了。但它仅仅是直觉,而不是真正的知识

push @{ $moved[$i] }, $address 
+3

在调试器中运行此操作,并在@addresses上放置一个手表。既然你正在做一个'while @地址',后来你做了一个'push @ adresses',我的小手指告诉我要注意一个永不减少的列表... – Konerak 2012-07-21 22:13:13

回答

0

我想我已经解决了它,以作为出发点的话,从'Konerak'。事实上这个问题是一个永不减少的列表。因为我对引用数组不熟悉,所以我有点迷失方向,但不知何故阅读代码,我试图找到预期行为的相似性。

所以我创建另一个数组称为@reserva我写这样的:

push @ {$reserva [$i]}, $address 

代替

push @addresses, $address; 

现在,我得到的名单我想不管我有多少邮件进入大小。我尝试了1000次,在不到一秒的时间内就没有问题。

所以,这里是完整的代码

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__ 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
0

这是一些曲折的代码,它是你遇到以下那就麻烦难怪。我并不确定代码的主体应该完成什么,但是您至少可以通过不使用while (@array) - 使用foreach my $item (@array)来避免无限循环,而是反复使用它,避免和产生出奇怪的行为修改循环内的数组。

chomp(@addresses); # chomp called on an array chomps each element 
foreach my $address (@addresses) { 
    # Do work here 
} 
+0

感谢你的评论,我会研究它。 – iaintunderstand 2012-07-24 15:54:15