最长公共子序列
来源:互联网 发布:汉诺塔递归算法解析 编辑:程序博客网 时间:2024/05/22 15:35
题目描述
给你俩个字符串,找公共最长的子序列串。
分析
根据第一个串的长度M,第二个串的长度N,建立一个MXN的二维表。
这个表 dp [i][j] ,代表 第一个串从 0 ~ i号下标和第二个串从0~j号下标这俩个字串的最长公共子序列。
那么这个表的初始状态是,dp[0][0]~dp[M-1][0]的值为,如果第一个串的 i 号元素跟第二个串的0号元素相等则值为1否则值为0,但是如果dp[i-1][0]的值为1,那么dp[i][0]的值也为1。因为i-1 是 i的字串,所以 i-1 有的公共字符在i中也一定有。对于dp[0][0]~dp[0][N-1]这个初始化跟上面这个类似。
那么dp[i][j]的公式是这样的,如果dp[i][j]可能有三种情况而来:
1.dp[i-1][j]来
2.dp[i][j-1]来
3.dp[i-1][j-1]来
那么就很简单了,分析下,dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]它们三个都相差一个字符,其中dp[i-1][j-1]又是它们俩个的子序列。那么它们的三个值如果相差最多差值为1。就在于这三个序列,一个新增了一个s1串的字符,一个新增了s2串的一个字符,一个没有新增。
那么新增s1串的字符的子序列,可能因为新增后又有一个公共子序列字符,那么dp[i][j]应该选它。新增s2串的字符的子序列同理。
那么可能,前面俩个新增后都没有多公共子序列字符,那么可能是第i个字符与第j个字符相等导致多了一个公共子序列的字符,那么这个时候dp[i][j]的值,就应该等于没有新增字符的dp[i-1][j-1]的值加1了。
用代码的思路就是,先从dp[i-1][j]与dp[i][j-1]中选个最大的,然后如果s1[i]==s2[j]的话,看dp[i-1][j-1]+1的值是否大于刚更新过的dp[i][j],如果大于重新更新下就Ok。
代码
#include<iostream>#include<vector>#include<string>using namespace std;void Getdp(std::string&s1 ,std::string&s2,vector<vector<int>>&ret){ int m = s1.size(); int n = s2.size(); for(int i=0;i<m;++i) { ret[i][0]=((s1[i]==s2[0]||(i>0&&ret[i][0]==1)))?1:0; } for(int i=0;i<n;++i) { ret[0][i]=((s2[i]==s1[0]||(i>0&&ret[0][i]==1)))?1:0; } for(int i=1;i<m;++i) { for(int j=1;j<n;++j) { ret[i][j]=(ret[i-1][j]>ret[i][j-1])?ret[i-1][j]:ret[i][j-1]; if(s1[i]==s2[j]&&ret[i-1][j-1]+1>ret[i][j]) ret[i][j]=ret[i-1][j-1]+1; } }}std::string GetSub(std::string & s1 ,std::string & s2 ){ vector<vector<int>> dp(s1.size()); for(auto&i:dp) { i.resize(s2.size()); } Getdp(s1,s2,dp); int m =s1.size(); int n =s2.size(); std::string ret; ret.resize(dp[m-1][n-1]); int count = ret.size()-1; int Row = m-1; int Col = n-1; while(count>=0) { if(Row>0&&dp[Row-1][Col]==dp[Row][Col]) --Row; else if(Col>0&&dp[Row][Col-1]==dp[Row][Col]) --Col; else { ret[count--]=s1[Row]; --Row,--Col; } } return ret;}int main(){ std::string s1 = "1A2C3D4B56"; std::string s2 = "B1D23CA45B6A"; std::string ret=GetSub(s1,s2); std::cout<<ret<<std::endl; return 0;}
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- HTML5拖拽
- java 省市区数据data
- 27 岁学编程是不是太晚了
- protractor中的browser.get
- nginx安装
- 最长公共子序列
- vue2.5 与 typescript 不知不说的那些事
- Python装饰器
- 日常累积
- centos7安装adobe解决网易云课堂视频的无法观看问题
- Windows平台下MongoDB安装配置
- static的简单介绍
- 资源管理器看不到WNetAddConnection2A映射的磁盘
- 字符设备驱动