2011-03-03 64 views
0

我遇到类似于此任务的问题: click (translated)(我分配的那个测试的方法更大,时间更短)。任务的快速翻译:在perl中发生SPOJ发生的速度问题

编写一个程序,检查给定序列中发生给定数量的次数。

输入:给定数量,有多少数字序列中,数字序列

输出:

我的解决方案,到目前为止出现的次数:

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; 

现在工作,谢谢:)

+0

数据集有多大?什么时间限制? :) – Orbit 2011-03-03 00:34:04

+0

spoj测试是秘密的,但我有一个示例测试,每行有1k行和600个数字。时间限制为1秒。我没有办法检查上面两个在spoj上运行多久:( – 2011-03-03 00:37:57

回答

3

首先,你做了很多复制。我每次标记你在你的第一个例子复制大串时间:

while (<>) { 
    $in = $_;     # COPY 
    @nums = split//, $in, 3; # COPY 

    $what = shift @nums; 
    shift @nums; 
    $rest = shift @nums;  # COPY 
    $rest = " ".$rest." ";  # COPY 

    $sum =() = $rest =~ /(?<=\s)$what(?=\s)/g; 

    print $sum; 
    print "\n"; 
} 

为了加快速度,避免了拷贝。例如,使用while ($in = <>)(或跳过$in并使用$_)。

对于提取$what和计数,我想我会尝试这个,而不是split

$in =~ s/^(\d+) \d+//; 
$what = $1; 

加空格前后相反的,只是使用\b代替lookarounds与\s

$sum =() = $in =~ /\b$what\b/g; 
+0

谢谢!不幸的是,它仍然太慢;( – 2011-03-03 09:01:04