题目说明:

找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。比如"bab"和"caba"的最长公共子串是"ba"和"ab"。

程序代码:

#include <gtest/gtest.h>
#include <vector>
#include <algorithm>
using namespace std; int GetLCS(const string& strA, const string& strB, vector<string>& result)
{
int nLengthA = strA.length();
int nLengthB = strB.length();
int nLongest = 0;
vector<int> vecSubStrEnd; if (!nLengthA || !nLengthB)
{
return 0;
} result.clear(); // strB
// 0 1 2 3 4 5 6 7 8
// 1
// s 2
// t 3
// r 4
// A 5
// 6 char* arrRecordInfo = new char[(nLengthA + 1) * (nLengthB + 1)];
memset(arrRecordInfo, 0, (nLengthA + 1) * (nLengthB + 1)); for (int i = 1; i <= nLengthA; ++i)
{
for (int j = 1; j <= nLengthB; ++j)
{
if (strA[i-1] == strB[j-1])
{
int nNewCount = arrRecordInfo[(i-1)*(nLengthB+1) + j-1] + 1;
if (nNewCount > nLongest)
{
nLongest = nNewCount;
vecSubStrEnd.clear();
vecSubStrEnd.push_back(j);
}
else if (nNewCount == nLongest)
{
vecSubStrEnd.push_back(j);
} arrRecordInfo[i*(nLengthB+1) + j] = nNewCount;
}
}
} for (int i=0; i < vecSubStrEnd.size(); ++i)
{
int nOffset = vecSubStrEnd[i];
result.push_back(strB.substr(nOffset-nLongest, nLongest));
}
// 移除重复公共字符串
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end()); delete[] arrRecordInfo; return nLongest;
} // 一种节省空间的方法
// 在构造这个二维矩阵的过程中由于得出矩阵的某一行后其上一行就没用了,所以实际上在程序中可以用一维数组来代替这个矩阵
// 如果把strB的长度假设为短的那个字符串,空间更少
int GetLCS2(const string& strA, const string& strB, vector<string>& result)
{
int nLengthA = strA.length();
int nLengthB = strB.length();
int nLongest = 0;
vector<int> vecSubStrEnd; if (!nLengthA || !nLengthB)
{
return 0;
} result.clear(); // strB
// 0 1 2 3 4 5
// 1
// s 2
// t 3
// r 4
// A 5
// 6 char* arrRecordInfo = new char[nLengthB+1];
memset(arrRecordInfo, 0, nLengthB+1); for (int i = 1; i <= nLengthA; ++i)
{
for (int j = nLengthB; j >= 1; --j)
{
if (strA[i-1] == strB[j-1])
{
int nNewCount = arrRecordInfo[j-1] + 1;
if (nNewCount > nLongest)
{
nLongest = nNewCount;
vecSubStrEnd.clear();
vecSubStrEnd.push_back(j);
}
else if (nNewCount == nLongest)
{
vecSubStrEnd.push_back(j);
} arrRecordInfo[j] = nNewCount;
}
else
{
arrRecordInfo[j] = 0;
}
}
} for (int i=0; i < vecSubStrEnd.size(); ++i)
{
int nOffset = vecSubStrEnd[i];
result.push_back(strB.substr(nOffset-nLongest, nLongest));
}
// 移除重复公共字符串
sort(result.begin(), result.end());
result.erase(unique(result.begin(), result.end()), result.end()); delete[] arrRecordInfo; return nLongest;
} TEST(Algo, tLongestCommonSubString)
{
//
// "" ""
// abcdefg bdacafg
// abcabcagc abcdcagb vector<string> result;
ASSERT_EQ(GetLCS("","",result),0);
ASSERT_EQ(GetLCS("abcdefg","bdacafg",result),2);
ASSERT_EQ(GetLCS("abcabcagc","abcdcagb",result),3); ASSERT_EQ(GetLCS2("abcdefg","bdacafg",result),2);
ASSERT_EQ(GetLCS2("abcabcagc","abcdcagb",result),3);
}

[算法练习]最长公共子串(LCS)的更多相关文章

  1. 最长公共子串(LCS:Longest Common Substring)

    最长公共子串(LCS:Longest Common Substring)是一个非常经典的面试题目,本人在乐视二面中被面试官问过,惨败在该题目中. 什么是最长公共子串 最长公共子串问题的基本表述为:给定 ...

  2. 最长公共子串LCS(Longest Common Substring)

    一.问题描述 寻求两个字符串中的最大公共字串,其中子串是指字符串中连续的字符组成的,而不是像子序列,按照字符的前后顺序组成.如str1="sgabacbadfgbacst",str ...

  3. 最长公共子串(LCS) lg SP1811

    后缀自动机的一大用处就是求最长公共子串了 这道题的话题意就是给你两个字符串,求最长公共子串 做法的话是先使用一个字符串建立SAM,然后让另一个串在上面进行匹配 匹配的策略是优先匹配当前节点的下一个字符 ...

  4. 求两个字符串的最长公共子串(LCS)

    http://tianyunpu2008.blog.163.com/blog/static/6559379920089162236915/

  5. 《算法导论》读书笔记之动态规划—最长公共子序列 & 最长公共子串(LCS)

    From:http://my.oschina.net/leejun2005/blog/117167 1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要 ...

  6. 华为OJ之最长公共子串

    题目描述: 对于两个给定的字符串,给出他们的最长公共子串. 题目分析: 1,最长公共子串(LCS)实际上是最长公共子序列的一种特殊情况,相当于是求连续的最长子序列.我们今天先解决这个特殊情况,后续博文 ...

  7. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  8. 【实习记】2014-08-29算法学习Boyer-Moore和最长公共子串(LCS)

        昨天的问题方案一:寻找hash函数,可行性极低.方案二:载入内存,维护成一个守护进程的服务.难度比较大.方案三:使用前5位来索引,由前3位增至前5位唯一性,理论上是分拆记录扩大100倍,但可以 ...

  9. 经典算法-最长公共子序列(LCS)与最长公共子串(DP)

    public static int lcs(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length() ...

随机推荐

  1. 使用UIGestureRecognizer监听屏幕事件

    转载自  http://blog.csdn.net/samguoyi/article/details/7911499 如果只是想获取屏幕点击事件有一个最简单的办法,就是写一个透明的uibutton覆盖 ...

  2. mysql无法启动 mysqld process already exists

    1.提示:A mysqld process already exists ps 命令用于查看当前正在运行的进程. grep 是搜索 例如: ps -ef | grep mysql 表示查看所有进程里 ...

  3. 规范打log

    在公司工作快3年了,debug用的最多的还是分析程序打出来的log. 怎样打log,打什么样的log,也是很值得研究的事情.好的打log方式,能够很快的分析和解决问题. 下面总结两点: 1.在log中 ...

  4. strlen() 和 sizeof() 在字符串中的使用

    #include <string.h> int _tmain(int argc, _TCHAR* argv[]) { char *pMyChar = "I like coding ...

  5. opennebula 出错截图与调试

  6. C++ assert()断言

    assert是一个宏定义,原型定义在<assert.h>中: #include <assert.h> void assert( int expression ); 其作用是:如 ...

  7. 浅析WINFORM工具条的重用实现

    一直以来,我都想看看别人家的工具栏重用(图1)到底是如何实现的,但在网上搜索了很久都没有找到过,即使找到一些程序,要么就是把这个工具栏写在具体的画面(图2),要么就是没有源代码的, 我在想,是否别人也 ...

  8. c语言操作符 “++”另类行为

    正常情况下,我们使用++ int a = 1; a++; printf(“%d”,a); // 2; 很简单没什么好说的. #include <stdio.h>   int main() ...

  9. Codeforces Educational Codeforces Round 5 A. Comparing Two Long Integers 高精度比大小,模拟

    A. Comparing Two Long Integers 题目连接: http://www.codeforces.com/contest/616/problem/A Description You ...

  10. sscanf和sprintf是scanf和printf家族用法 (转)

    sscanf和sprintf是scanf和printf家族用法 sscanf和sprintf是scanf和printf家族的一对成员,用于处理和分析字符串非常强大得两个函数头文件 stdio.h原型i ...