最长公共字串(Longest Common Substring)

1. 问题描述

 

2. 动态规划解

设 A 和 B 分别为长度为 m 和 n 的序列,用 opt[i, j] 表示 A[1 : i] 与 B[1 : j] 的且末位为 Ai (==Bj) 的公共子串的长度。则

  • opt[0, j] = 0, opt[i, 0] = 0
  • 如果 Ai == Bj, opt[i, j] = opt[i - 1, j - 1]  + 1
  • 如果 Ai!= Bj, opt[i, j] = 0

3. C++实现

// Longest Common Substring
template<class Iter1, class Iter2>
std::tuple<int, Iter1, Iter1> LCSstr(const Iter1 &beg1, const Iter1 &end1, const Iter2 &beg2, const Iter2 &end2)
{
    int m = end1 - beg1;
    int n = end2 - beg2;
    std::vector<int> opt1(n + 1, 0);
    std::vector<int> opt2(n + 1, 0);

    Iter1 beg_opt = beg1;
    Iter2 end_opt = beg1;
    int length_opt = 0;
    Iter1 id1 = beg1;
    Iter2 id2;
    for(int i = 1; i <= m; ++i, ++id1)
    {
        id2 = beg2;
        for(int j = 1; j <= n; ++j, ++id2)
        {
            if(*id1 == *id2)
            {
                opt2[j] = opt1[j - 1] + 1;
                if(opt2[j] > length_opt)
                {    
                    length_opt = opt2[j];
                    end_opt = std::next(id1);
                }
            }
            else
                opt2[j] = 0;
        }
        if(i < m)
            opt1.swap(opt2);
    }

    beg_opt = std::prev(end_opt, length_opt);
    return std::make_tuple(length_opt, beg_opt, end_opt);
}

4. 分析

空间复杂度 O(n)

时间复杂度 O(m * n)

 

posted @ 2013-09-20 22:05  半亩梨花  阅读(203)  评论(0编辑  收藏  举报