首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Knuth Morris Pratt算法在Perl中的实现

Knuth Morris Pratt算法在Perl中的实现
EN

Stack Overflow用户
提问于 2013-05-12 03:26:32
回答 1查看 578关注 0票数 1

我正在尝试用Perl实现Knuth Morris Pratt algorithm。下面是我的代码,我引用了Perl First Edition中的精通算法。当我运行代码时,它会输出-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1-1-1-1。我哪里错了?

代码:

代码语言:javascript
运行
复制
#!/usr/local/bin/perl

#text
my $seq = "babacbadbbac";

#pattern
my $motif = "acabad";

#pass the text and pattern to knuth_morris_pratt subroutine
my @res = knuth_morris_pratt($seq, $motif);

#print the result
print "The resulting array is:";
print "@res";

#computation of the prefix subroutine
sub knuth_morris_pratt_next
{
   my($P) = @_; #pattern
   use integer;
   my ( $m, $i, $j ) = ( length $P, 0, -1 );
   my @next;
   for ($next[0] = -1; $i < $m; ) {
      # Note that this while() is skipped during the first for() pass.
      while ( $j > -1 && substr( $P, $i, 1 ) ne substr( $P, $j, 1 ) ) {
         $j = $next[$j];
      }
      $i++;
      $j++;
      $next[$i] = substr( $P, $j, 1 ) eq substr( $P, $i, 1 ) ? $next[$j] : $j;
   }
   return ( $m, @next ); # Length of pattern and prefix function.
}

#matcher subroutine
sub knuth_morris_pratt
{
   my ( $T, $P ) = @_; # Text and pattern.
   use integer;
   my ($m,@next) = knuth_morris_pratt_next( $P );
   my ( $n, $i, $j ) = ( length($T), 0, 0 );
   #my @next;
   my @val;
   my $k=0;
   while ( $i < $n ) 
   {
      while ( $j > -1 && substr( $P, $j, 1 ) ne substr( $T, $i, 1 ) ) 
      {
         $j = $next[$j];
      }
      $i++;
      $j++;
      if($j>=$m)
      {
          $val[$k]= $i - $j; # Match.
      }
      else
      {
          $val[$k]=-1; # Mismatch.
      }
      $k++;
   }
   return @val; 
}
EN

回答 1

Stack Overflow用户

发布于 2013-05-12 08:30:49

KMP算法的实现返回一个数组,对于seq的每个位置,在motif不匹配的位置返回-1,在匹配的位置返回匹配的索引。

例如,如果将motif更改为"acbad“,则数组还将包含一个3:

代码语言:javascript
运行
复制
 0  1  2  3  4  5  6  7  8  9  10  11   | index
"b  a  b  a  c  b  a  d  b  b  a   c"   | seq
         "a  c  b  a  d"                | motif 
代码语言:javascript
运行
复制
$> perl mq.pl "babacbadbbac" "acabad"
The resulting array is:
[-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] [-1] 

$> perl mq.pl "babacbadbbac" "acbad"
Match at index:3 
The resulting array is:
[-1] [-1] [-1] [-1] [-1] [-1] [-1] [3] [-1] [-1] [-1] [-1] 


$> perl mq.pl "babacbadbbac" "ac" 
Match at index:3 
Match at index:10 
The resulting array is:
[-1] [-1] [-1] [-1] [3] [-1] [-1] [-1] [-1] [-1] [-1] [10] 

修改后的代码

代码语言:javascript
运行
复制
#!/usr/local/bin/perl

my($seq,$motif) = @ARGV;

die "seq and motif required..." unless $seq and $motif;
die "motif should be <= seq ..." unless  length($motif) <= length($seq);

#pass the text and pattern to knuth_morris_pratt subroutine
my @res = knuth_morris_pratt($seq, $motif);

#print the result
print "The resulting array is:\n";
#print "@res";
print "[".join("] [",@res)."] \n";
#computation of the prefix subroutine
sub knuth_morris_pratt_next
{
   my($P) = @_; #pattern
   use integer;
   my ( $m, $i, $j ) = ( length $P, 0, -1 );
   my @next;
   for ($next[0] = -1; $i < $m; ) {
      # Note that this while() is skipped during the first for() pass.
      while ( $j > -1 && substr( $P, $i, 1 ) ne substr( $P, $j, 1 ) ) {
         $j = $next[$j];
      }
      $i++;
      $j++;
      $next[$i] = substr( $P, $j, 1 ) eq substr( $P, $i, 1 ) ? $next[$j] : $j;
   }
   return ( $m, @next ); # Length of pattern and prefix function.
}

#matcher subroutine
sub knuth_morris_pratt
{
   my ( $T, $P ) = @_; # Text and pattern.
   use integer;
   my ($m,@next) = knuth_morris_pratt_next( $P );
   my ( $n, $i, $j ) = ( length($T), 0, 0 );
   #my @next;
   my @val;
   my $k=0;
   while ( $i < $n ) 
   {
      while ( $j > -1 && substr( $P, $j, 1 ) ne substr( $T, $i, 1 ) ) 
      {
         $j = $next[$j];
      }
      $i++;
      $j++;
      if($j>=$m)
      {
          $val[$k]= $i - $j; # Match.
          print "Match at index:".$val[$k]." \n";
      }
      else
      {
          $val[$k]=-1; # Mismatch.
      }
      $k++;
   }
   return @val; 
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16500902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档