一、题目描述

描述:

计算两个字符串的最大公共子串(Longest Common Substring)的长度,字符区分大小写。

输入:

输入两个字符串

输出:

输出一个整数

样例输入:

asdfas werasdfaswer

样例输出:

6

二、解题报告

与最长公共子序列(参见《动态规划DP》)一样,最长公共子串也可以使用动态规划解决,只不过思路不太一样。准确地说,是打表的方式不一样。

举个例子:s1 = bab,s2 = caba。表如下

具体打表的方法是:

  • 第一行、第一列初始化为 0;
  • 对于其他的格子:
    • 若对应的两个字符相等,格子的值设为左上角的值加 1。
    • 若对应的两个字符不相等,直接置 0 。

这样的话,表中的最大元素就是 最长公共子串 的长度。并且也可以很容易看出最长公共子串有 2 个,分别是baab

C++代码如下:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std; int getLCStringLength(string s1, string s2)
{
if(s1 == "" || s2 == "")
return 0; int m = s1.size();
int n = s2.size();
vector<vector<int> > table(m+1, vector<int>(n+1)); int biggest = 0; // 记录表中最大值
for(int i=0; i<m+1; ++i)
{
for(int j=0; j<n+1; ++j)
{
// 第一行和第一列置0
if (i == 0 || j == 0)
table[i][j] = 0; else if(s1[i-1] == s2[j-1])
{
table[i][j] = table[i-1][j-1] + 1;
if(table[i][j] > biggest)
biggest = table[i][j];
} else // 不相等置0
table[i][j] = 0;
}
}
return biggest;
} int main ()
{
string input, s1, s2;
getline(cin, input);
stringstream ss(input);
ss >> s1;
ss >> s2;
cout << getLCStringLength(s1, s2) << endl; return 0;
}

三、扩展

如何输出所有的最长公共子串?

很简单,我们记录下 s1 和 s2 的公共子串分别在 s1 、s2 中起始位置(即表中值为 1 的坐标)。打表完成以后,我们已经知道了最长公共子串的长度length,通过substr()判断即可:

s1.substr(i-1, length) == s2.substr(j-1, length)

C++代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std; void printLCString(string s1, string s2)
{
if(s1 == "" || s2 == "")
return; int m = s1.size();
int n = s2.size();
vector<vector<int> > table(m+1, vector<int>(n+1)); int biggest = 0; // 记录表中最大值
vector<pair<int, int> > firstPos; // 记录子串开始的坐标
for(int i=0; i<m+1; ++i)
{
for(int j=0; j<n+1; ++j)
{
// 第一行和第一列置0
if (i == 0 || j == 0)
table[i][j] = 0;
else if(s1[i-1] == s2[j-1])
{
table[i][j] = table[i-1][j-1] + 1;
if(table[i][j] > biggest)
biggest = table[i][j];
if(table[i][j] == 1)
firstPos.push_back(make_pair(i, j));
}
else // 不相等置0
table[i][j] = 0;
}
} // 输出所有的最长公共子串
vector<pair<int, int> >::iterator beg = firstPos.begin();
for( ; beg!=firstPos.end(); ++beg)
{
int start1 = beg->first-1;
int start2 = beg->second-1;
if(s1.substr(start1, biggest) == s2.substr(start2, biggest))
cout << s1.substr(start1, biggest) << endl;
}
} int main ()
{
string s1 = "hello,world,james";
string s2 = "james is saying hello";
printLCString(s1, s2); return 0;
}

个人站点:http://songlee24.github.com

华为OJ2011-最长公共子串的更多相关文章

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

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

  2. 最长公共子串(Longest common substring)

    问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子串.(子串中的字符要求连续) 这道题和最长公共 ...

  3. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

  4. HDU 1503 带回朔路径的最长公共子串

    http://acm.hdu.edu.cn/showproblem.php?pid=1503 这道题又WA了好几次 在裸最长公共子串基础上加了回溯功能,就是给三种状态各做一个 不同的标记.dp[n][ ...

  5. 最长公共子序列PK最长公共子串

    1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. (1)递归方法求最长公共子序列的长度 1) ...

  6. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  7. 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

    Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...

  8. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message

    Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21 ...

  9. 最长公共子串 NYOJ 36

    http://acm.nyist.net/JudgeOnline/problem.php?pid=36 最长公共子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 ...

随机推荐

  1. 玩一把redis源码(一):为redis添加自己的列表类型

    2019年第一篇文档,为2019年做个良好的开端,本文档通过step by step的方式向读者展示如何为redis添加一个数据类型,阅读本文档后读者对redis源码的执行逻辑会有比较清晰的认识,并且 ...

  2. automount - 配置autofs的挂载点

    命令概要(SYNOPSIS) automount [options] mount-point map-type[,format] map [map-options] 描述(DESCRIPTION) a ...

  3. node.js编译less文件

    大多数文章对于到底怎样编译less文件并没有一个详细的说明,清一色的grunt命令,看得也是晕晕的,所以也就有了这篇手记的存在. 步入正题 1.安装配置好sublime text3(包括各种实用插件) ...

  4. Python框架Django的入门

    本篇文章主要给大家介绍Django的入门知识:

  5. 查找BUG的方法

    1)测试环境 1)代码调试 2)问题重现 3)思考问题所在 2)生产环境 1)思考 2)测试本地环境是否存在问题 3)打开日志查看 4)思考是否是数据原因 5)拷贝数据到本地进行重现 3)未知错误 1 ...

  6. 将java project打包成jar包,web project 打包成war包的几种演示 此博文包含图片

    转: http://blog.csdn.net/christine_ruan/article/details/7491559 http://developer.51cto.com/art/200907 ...

  7. Autorelease pools 官方文档

    翻译自: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAu ...

  8. viewDidLoad等相关函数调用

    viewDidLoad 此方法只有当view从nib文件初始化的时候才被调用.viewDidLoad用于初始化,加载时用到的. loadView 此方法在控制器的view为nil的时候被调用.虽然经常 ...

  9. Sublime Text3 学习笔记

    注:以下记录自己的 Sublime Text3学习过程(持续更新中) 目录: 安装 下载文件 破解试用 插件安装 安装 Sublime Text 是一套跨平台的文本编辑器,支持基于Python的插件. ...

  10. js 实现弹力球效果

    1.html代码: <div id='imgid'> <img src="img/5.png"> </div> 2.js代码: imgobj=d ...