【发布时间】:2011-03-03 00:28:46
【问题描述】:
我在执行与此类似的任务时遇到问题: click (translated)(分配给我的测试更大,时间限制更短)。任务的快速翻译:
编写一个程序,检查给定数字在给定序列中出现的次数。
输入:给定数字,序列中有多少个数字,数字的序列
输出:出现次数
到目前为止我的解决方案:
1:
#!/usr/bin/env perl
while (<>) {
$in = $_;
@nums = split / /, $in, 3;
$what = shift @nums;
shift @nums;
$rest = shift @nums;
$rest = " ".$rest." ";
$sum = () = $rest =~ /(?<=\s)$what(?=\s)/g;
print $sum;
print "\n";
}
2:
#!/usr/bin/env perl
while (<>) {
$in = $_;
@nums = split / /, $in, 3;
$what = shift @nums;
shift @nums;
$rest = shift @nums;
$rest = " ".$rest." ";
if(!$reg{$what}){
$reg{$what} = qr/(?<=\s)$what(?=\s)/;
}
$sum = () = $rest =~ /$reg{$what}/g;
print $sum;
print "\n";
}
我还尝试了蛮力方法、哈希表、grep... 都超过了给定的时间限制,而且我不知道如何编写比上述两个更快的方法。有什么想法吗?
编辑:摆脱复制列表后(结果数字也可以是负数):
#!/usr/bin/env perl
while ($line = <>) {
$line =~ s/^(-?\d+) \d+//;
$what = $1;
$sum = () = $line =~ / $what\b/g;
print $sum;
print "\n";
}
edit2:通过http://www.chengfu.net/2005/10/count-occurrences-perl/:
print $sum = (($line =~ s/ $1\b//g)+0);
产生的代码比以下代码快 2 倍:
print $sum = () = $line =~ / $1\b/g;
现在可以使用了,谢谢:)
【问题讨论】:
-
数据集有多大,时间限制是多少? :)
-
spoj 测试是秘密的,但我得到了一个示例测试,其中包含 1k 行和每行约 600 个数字。时间限制为1s。我无法检查以上两个在 spoj 上运行了多长时间 :(
标签: perl optimization