最长公共子串问题 动态规划

来源:互联网 发布:家用健身器材 知乎 编辑:程序博客网 时间:2024/06/05 00:12

1、问题描述:来源于《算法与数据结构题目最优解》左程云著

给定两个字符串str1和str2,返回两个字符串的最长公共子串,例如:str1="1AB2345CD",str2="12345EF",返回"2345"


2、问题分析

1)这个题目看起来和最长公共子序列很相似,在第一遍做的时候我也是做成了最长公共子序列,但是公共子串必须是连续的;

2)问题的关键在于状态的寻找,我觉得这个题目的状态不好找;最长公共子序列的状态dp[i][j]代表str1长度为i,str2长度为j时的子序列长度;本题目的状态dp[i][j]代表在必须把str1[i]和str2[j]当做公共子串最后一个字符的情况下,公共子串的长度。

3)上面的状态就代表如果str1[i]!=str2[j],那么就没法构成公共子串,那么此时dp[i][j]就为0;如果两者相等,那么dp[i][j]=dp[i-1][j-1]+1。

4)获得了最大的长度,然后再知道i或者j的值,就可以求出公共子串了。


3、下面是代码(以后会注意代码的模块化,方便阅读和理解)

#include<iostream>#include<vector>#include<string>using namespace std;int main() {int len1, len2;//两个字符串的长度int i, j;//辅助变量string str1, str2;getline(cin, str1);getline(cin, str2);len1 = str1.length();len2 = str2.length();vector<vector<int>>dp(len1, vector<int>(len2));//dp[i][j]表示必须以str1[i]和str2[j]结尾的公共子串的最大长度,也就是str1[i]必须等于str2[j]//计算公共子串的长度for (i = 0; i < len1; ++i) {if (str1[i] == str2[0])dp[i][0] = 1;elsedp[i][0] = 0;}for (j = 0; j < len2; ++j) {if (str2[j] == str1[0])dp[0][j] = 1;elsedp[0][j] = 0;}for (i = 1; i < len1; ++i) {for (j = 1; j < len2; ++j) {if (str1[i] != str2[j]) {dp[i][j] = 0;}else {dp[i][j] = dp[i - 1][j - 1] + 1;}}}//得出公共子串的最大长度,并且记录位置int pos, val = 0;for (i = 0; i < len1; ++i) {for (j = 0; j < len2; ++j) {if (val < dp[i][j]) {pos = i;val = dp[i][j];}}}//输出结果for (i = pos - val + 1; i <= pos; ++i) {cout << str1[i];}cout << endl;}

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 香氛蜡烛记忆环怎么办 我吃了马兜铃怎么办呀 肝肾衰弱有毒素怎么办 肾阴虚阳虚都有怎么办 吃辣刺激胃疼怎么办 舌头没有舌苔有裂纹疼痛怎么办 舌苔厚黄是怎么回事且口臭怎么办 舌苔厚白是怎么回事且口臭怎么办 长期有舌苔白厚怎么办 小孩的舌苔厚白怎么办 口苦口臭舌苔黄怎么办 婴儿的舌苔厚白怎么办 舌苔黄厚口臭痒怎么办 想让月经提前来怎么办 宝宝拉肚子怎么办吃什么好 投资p2p跑路了怎么办 借钱不还怎么办最有效 朋友借小钱不还怎么办 网络上贷款不还怎么办 网贷实在还不了怎么办 娱乐平台跑路了怎么办 360借条被拒了怎么办 网贷注册太多了怎么办 汽车大绿本丢了怎么办 网贷平台跑路怎么办 电脑中了1kb病毒怎么办 360网页走丢了怎么办 被信和汇金起诉怎么办 qq号搜不到好友怎么办 gta5买的车炸了怎么办 ipad千牛缩小了怎么办 求生之路2卡顿怎么办 仙剑奇侠传1凤凰怎么办打 水温报警灯亮了怎么办 遇到拿刀的歹徒怎么办 微信公众号被骗怎么办 苹果ad账号忘了怎么办 苹果手机想换id怎么办 苹果6按键不会动怎么办 app充值不到账怎么办 卡被取款机吞了怎么办