题目说明:

找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。比如"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. LeetCode7:Reverse Integer

    Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 click to ...

  2. 检测iOS的APP性能的一些方法

    首先如果遇到应用卡顿或者因为内存占用过多时一般使用Instruments里的来进行检测.但对于复杂情况可能就需要用到子线程监控主线程的方式来了,下面我对这些方法做些介绍: Time Profiler ...

  3. ManagementFactory (二) getMemoryMXBean

    MemoryMXBean package cn.zno.outofmomery; import java.lang.management.ManagementFactory; import java. ...

  4. zendstudio 出现failed to create the java machine转

    是因为配置java虚拟机内存太小 打开zend for eclipse 10.5时报了个错: failed to create the java virtual machine google了一下,解 ...

  5. jquery easyui datagraid 对象显示的方法与datagraid、分页、复选框多选的数据显示

    ========================jsp==============================<table id="dg" fit="true& ...

  6. 动态链接--so的搜索过程

    可执行文件所依赖的so路径保存在.dynamic 里面,由DT_NEED类型表示.如下: 如果DT_NEED里面保存的是绝对路径,那ld就在绝对路径下查找so. 如果DT_NEED里面保存的是相对路径 ...

  7. ASP.NET MVC- 在Area里使用RedirectToAction跳转出错的解决方法

    mvc使用Area分区开发后,存在不同Area之间的跳转,需要为每个区间添加Area规则,如下: 按 Ctrl+C 复制代码 using System.Web.Mvc; namespace web.A ...

  8. STL中vector容器实现反转(reverse)

    vector容器中实现可以通过以下两种方式实现: #include "stdafx.h" #include <vector> #include <iostream ...

  9. System.Data.SQLite数据库简介

    SQLite介绍 在介绍System.Data.SQLite之前需要介绍一下SQLite,SQLite是一个类似于Access的单机版数据库管理系统,它将所有数据库的定义(包括定义.表.索引和数据本身 ...

  10. C++的优秀特性2:inline 函数

    (转载请注明原创于潘多拉盒子) Inline函数是C++的一个很小的特性,在不计较效率的情况下,这个特性似乎可有可无.然而,C++天生是为最为广泛的应用场景设计的,因此,总会有关于效率的问题.其实,除 ...