use warnings;
use strict;
my $in=<STDIN>;
my @array=(1...$in);
foreach my $j(2...sqrt($in)){
for(my $i=$j*2;$i<=$in;$i+=$j){
delete($array[$i-1]);
}
}
delete($array[0]);
open FILE, ">","I:\\Perl_tests\\primes.dat";
foreach my $i (@array){
if($i){
print FILE $i,"\n";
}
}
我确信有更好的方法来处理所有数字的数组但是我真的不知道在perl中这样做的方法。我对perl很缺乏经验。任何加快它的建议都非常感谢。万分感谢!
答案 0 :(得分:1)
最快的解决方案是使用模块(例如ntheory),如果你只是想要素数而不关心你是如何得到的。这将大大加快并且使用更少的内存。
我建议查看the RosettaCode Sieve task。显示了许多简单的筛子,快速的字符串版本,一些奇怪的例子,以及几个可扩展的筛子。
即使是基本的内存比你的例子使用更少的内存,并且那里显示的矢量和字符串版本使用的内存要少得多。
除非你是丹·伯恩斯坦,否则阿特金的筛子很少是一种好方法。即使这样,它也比快速SoE实现慢。
答案 1 :(得分:0)
这是寻找素数的一种相当低效的方法,所以除非你绝对必须使用Erastosthenes的Sieve,The Sieve of Atkin可能是一种更快的查找素数的算法。
关于内存使用情况,这里是this python answer的perlified版本。它不是从所有整数的大前沿数组中找出数字,而是跟踪哪些素数是非素数的除数,然后在每次迭代后屏蔽下一个非素数。这意味着您可以生成尽可能多的质数,而无需使用所有RAM,或者不必使用任何内存。更多的代码和更多的间接使得这个版本比你已经的版本慢。
#!/usr/bin/perl
use warnings;
use strict;
sub get() {
my $this = shift;
if ($this->{next} == 2) {
$this->{next} = 3;
return 2;
}
while (1) {
my $next = $this->{next};
$this->{next} += 2;
if (not exists $this->{used}{$next}) {
$this->{used}{$next * $next} = [$next];
return $next;
} else {
foreach my $x (@{$this->{used}{$next}}) {
push (@{$this->{used}{$next + $x}}, $x);
}
delete $this->{used}{$next};
}
}
}
sub buildSieve {
my $this = {
"used" => {},
"next" => 2,
};
bless $this;
return $this;
}
my $sieve = buildSieve();
foreach $_ (1..100) {
print $sieve->get()."\n";
}
你应该能够将更好的算法与上面更具记忆效率的生成版本结合起来,以提出一个很好的解决方案。
如果您想详细了解算法的工作原理,use Data::Dumper;
非常有启发性,并且在每次调用$sieve
之间打印get()
。