用于查找两个字符串的重叠区域的Perl模块或代码

时间:2014-06-06 14:00:59

标签: perl textmatching

我有两个字符串。

它们不是彼此的子串,但它们之间存在重叠区域。

my $str1 = "AAAAAAAAAABBBBBBBBCC";
my $str2 = "BBBBBBBBCCZZZZZZZZZZ";

我想找到这个重叠的区域。

 "AAAAAAAAAABBBBBBBBCC"
           "BBBBBBBBCCZZZZZZZZZZ"

Overlap is "BBBBBBBBCC"

我搜索了CPAN并广泛搜索。

有很多模块关于" 编辑距离" Algorithm::DiffText::LevenshteinText::OverlapFinderString::Similarity等方法。 但是,它们不是我想要的。

字符串不应 gaped (插入或删除任何字符)或替换。 它与生物信息学中的序列比对相似,但没有差距"开放"和"扩展"许可,除非在两个极端。

我想知道是否有人找到了解决方案或解决方法。

2 个答案:

答案 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