基础上general algorithm,但不是唯一跟踪当前运行(@l
)的长度,而是它是否包含关键字(@k
)。只有包含关键字的运行才被考虑为最长运行时间。
use strict;
use warnings;
use feature qw(say);
sub find_substrs {
our $s; local *s = \shift;
our $key; local *key = \shift;
my @positions;
my $position = -1;
while (1) {
$position = index($s, $key, $position+1);
last if $position < 0;
push @positions, $position;
}
return @positions;
}
sub lcsubstr_which_include {
our $s1; local *s1 = \shift;
our $s2; local *s2 = \shift;
our $key; local *key = \shift;
my @key_starts1 = find_substrs($s1, $key)
or return;
my @key_starts2 = find_substrs($s2, $key)
or return;
my @is_key_start1; $is_key_start1[$_] = 1 for @key_starts1;
my @is_key_start2; $is_key_start2[$_] = 1 for @key_starts2;
my @s1 = split(//, $s1);
my @s2 = split(//, $s2);
my $length = 0;
my @rv;
my @l = (0) x (@s1 + 1); # Last ele is read when $i1==0.
my @k = (0) x (@s1 + 1); # Same.
for my $i2 (0..$#s2) {
for my $i1 (reverse 0..$#s1) {
if ($s1[$i1] eq $s2[$i2]) {
$l[$i1] = $l[$i1-1] + 1;
$k[$i1] = $k[$i1-1] || ($is_key_start1[$i1] && $is_key_start2[$i2]);
if ($k[$i1]) {
if ($l[$i1] > $length) {
$length = $l[$i1];
@rv = [ $i1, $i2, $length ];
}
elsif ($l[$i1] == $length) {
push @rv, [ $i1, $i2, $length ];
}
}
} else {
$l[$i1] = 0;
$k[$i1] = 0;
}
}
}
for (@rv) {
$_->[0] -= $length;
$_->[1] -= $length;
}
return @rv;
}
{
my $s1 = "peachbananaapplepear";
my $s2 = "juicenaapplewatermelonpear";
my $key = "apple";
for (lcsubstr_which_include($s1, $s2, $key)) {
my ($s1_pos, $s2_pos, $length) = @$_;
say substr($s1, $s1_pos, $length);
}
}
这个解决方案在O(NM)中,意思是它的尺寸非常好(因为它的功能)。
'$ 1'可以包含该代码中的任何内容(包括“橙色”)。我修正了它,但鲍罗丁没有解释就恢复了修复。 – ikegami
真的......我通常会在询问$ 1的价值之前检查以确保比赛成功。 –
即使有修复,它也不会做OP所要求的。它只是检查'$ string2'是否包含'apple'。 – ikegami