我有两个字符串。
它们不是彼此的子串,但它们之间存在重叠区域。
my $str1 = "AAAAAAAAAABBBBBBBBCC";
my $str2 = "BBBBBBBBCCZZZZZZZZZZ";
我想找到这个重叠的区域。
"AAAAAAAAAABBBBBBBBCC"
"BBBBBBBBCCZZZZZZZZZZ"
Overlap is "BBBBBBBBCC"
我搜索了CPAN并广泛搜索。
有很多模块关于" 编辑距离" Algorithm::Diff
,Text::Levenshtein
或Text::OverlapFinder
和String::Similarity
等方法。
但是,它们不是我想要的。
字符串不应 gaped (插入或删除任何字符)或替换。 它与生物信息学中的序列比对相似,但没有差距"开放"和"扩展"许可,除非在两个极端。
我想知道是否有人找到了解决方案或解决方法。
答案 0 :(得分:4)
检查String::LCSS_XS
模块,
use String::LCSS_XS 'lcss';
my ($s1,$s2) = qw(
AAAAAAAAAABBBBBBBBBB
BBBBBBBBBBCCCCCCCCCC
);
my $longest = lcss ($s1, $s2);
print "$longest\n";
输出
BBBBBBBBBB
答案 1 :(得分:1)
因为你正在寻找有界重叠,这是一个简单的问题,蛮力是要走的路。均衡字符串长度,然后切断字符直到找到匹配项。
有一些潜在的途径可以提高效率,但只会探索那些因为速度太慢的原因。
use strict;
use warnings;
sub overlap {
my ($str1, $str2) = @_;
# Equalize Lengths
if (length $str1 < length $str2) {
$str2 = substr $str2, 0, length($str1);
} elsif (length $str1 > length $str2) {
$str1 = substr $str1, length($str1) - length($str2);
}
# Reduce until match found
while ($str1 ne $str2) {
substr $str1, 0, 1, '';
chop $str2;
}
return $str1;
}
while (<DATA>) {
print "Overlap is " . overlap(split), "\n";
}
__DATA__
AAAAAAAAAABBBBBBBBBB BBBBBBBBBBCCCCCCCCCC
aln.trp.leu.tre leu.tre.met.ile
aaaaaaaaaaaaaaaaaaaZ aaaaaaaaaaaaaaa
输出:
Overlap is BBBBBBBBBB
Overlap is leu.tre
Overlap is