华为OJ2011-最长公共子串
一、题目描述
描述:
计算两个字符串的最大公共子串(Longest Common Substring)的长度,字符区分大小写。
输入:
输入两个字符串
输出:
输出一个整数
样例输入:
asdfas werasdfaswer
样例输出:
6
二、解题报告
与最长公共子序列(参见《动态规划DP》)一样,最长公共子串也可以使用动态规划解决,只不过思路不太一样。准确地说,是打表的方式不一样。
举个例子:s1 = bab,s2 = caba。表如下
具体打表的方法是:
- 第一行、第一列初始化为 0;
- 对于其他的格子:
- 若对应的两个字符相等,格子的值设为左上角的值加 1。
- 若对应的两个字符不相等,直接置 0 。
这样的话,表中的最大元素就是 最长公共子串 的长度。并且也可以很容易看出最长公共子串有 2 个,分别是ba和ab。
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;
}
华为OJ2011-最长公共子串的更多相关文章
- 华为OJ之最长公共子串
题目描述: 对于两个给定的字符串,给出他们的最长公共子串. 题目分析: 1,最长公共子串(LCS)实际上是最长公共子序列的一种特殊情况,相当于是求连续的最长子序列.我们今天先解决这个特殊情况,后续博文 ...
- 最长公共子串(Longest common substring)
问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子串.(子串中的字符要求连续) 这道题和最长公共 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- HDU 1503 带回朔路径的最长公共子串
http://acm.hdu.edu.cn/showproblem.php?pid=1503 这道题又WA了好几次 在裸最长公共子串基础上加了回溯功能,就是给三种状态各做一个 不同的标记.dp[n][ ...
- 最长公共子序列PK最长公共子串
1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. (1)递归方法求最长公共子序列的长度 1) ...
- 动态规划(一)——最长公共子序列和最长公共子串
注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
Language: Default Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 21 ...
- 最长公共子串 NYOJ 36
http://acm.nyist.net/JudgeOnline/problem.php?pid=36 最长公共子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 ...
随机推荐
- C#反射的使用
1.先定义个类,编译成dll,用于调用 nameSpace Test{ public class Class1 { private string _name; private int _age; pu ...
- CAD参数绘制圆(com接口)
CAD绘制图像的过程中,画圆的情况是非常常见的,用户可以设置圆的圆心位置及半径属性. 主要用到函数说明: _DMxDrawX::DrawCircle 绘制一个圆.详细说明如下: 参数 说明 DOUBL ...
- vue-cli 中使用less
(1)安装Less模块: npm install less (2)安装less和less-loader,命令如下 npm install less less-loader --sava-dev (3) ...
- 获取汉字的拼音首字母--pinyin
var pinyin = (function (){ var Pinyin = function (ops){ this.initialize(ops); }, options = { checkPo ...
- DNS服务器原理简述、搭建主/从DNS服务器并实现智能解析
1. TLD:Top Level Domain 顶级域名 组织域:.com, .net, .org, .gov, .edu, .mil 国家域:.iq, .tw, .hk, .jp, .cn, ... ...
- linux nslookup-查询域名DNS信息的工具
博主推荐:更多网络测试相关命令关注 网络测试 收藏linux命令大全 nslookup命令是常用域名查询工具,就是查DNS信息用的命令. nslookup4有两种工作模式,即“交互模式”和“非交互模 ...
- centos 简单用户管理
一.配置文件 /etc/passwd:存放用户信息,以“:”分割成7个部分 1.账号名称,用来对应UID: 2.早期密码存放位置,后来密码改存/etc/shadow中,以“x”代替: 3.UID,使用 ...
- DFS求连通块(漫水填充法)
G - DFS(floodfill),推荐 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I6 ...
- MySQL MGR源码分析2 - 从start group_replication看MGR代码框架
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 上一篇我们从方案层面讲解了MGR的成员管理和故障恢复.本篇从源码层面捋一捋,通过本篇介绍,除了能够了解如何将 ...
- 洛谷 P2285 BZOJ 1207 [HNOI2004]打鼹鼠
题目描述 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气. ...