公共字串计算(最长公共子串/序列)C++
来源:互联网 发布:nginx 400 错误 编辑:程序博客网 时间:2024/05/17 05:57
题目
描述
题目标题:
计算两个字符串的最大公共字串的长度,字符不区分大小写
输入
输入两个字符串
输出
输出一个整数
样例输入
asdfas werasdfaswer
样例输出
6
思路
暴力求解
此题用cin即可
代码
#include <iostream>#include <string>using namespace std;int Maxsubstr(string a,string b){ unsigned int start1,start2; int count=0,Max=0; for(unsigned int i=0; a[i]!='\0'; i++) { for(unsigned int j=0; b[j]!='\0'; j++) { start1=i; start2=j; while(a[start1]==b[start2] && start1<a.length() && start2<b.length()) { start1++; start2++; count++; } if(count>Max) { Max=count; } count=0; } } return Max;}int main(){ string str1,str2; cin>>str1; cin>>str2; //不区分大小写 for (unsigned int i=0; i<str1.length(); i++) { str1[i]=tolower(str1[i]); } for (unsigned int i=0; i<str2.length(); i++) { str2[i]=tolower(str2[i]); } cout<<Maxsubstr(str1,str2)<<endl;}
题目
描述
查找两个字符串a,b中的最长公共子串。
详细描述:
查找两个字符串a,b中的最长公共子串。
输入
输入两个字符串
输出
返回重复出现的字符
样例输入
abcdefghijklmnop
abcsafjklmnopqrstuvw
样例输出
jklmnop
思路
暴力求解
代码
#include <iostream>#include <string>using namespace std;int Maxsubstr(string a,string b,string *&s){ unsigned int start,start1,start2; int count=0,Max=0; for(unsigned int i=0; a[i]!='\0'; i++) { for(unsigned int j=0; b[j]!='\0'; j++) { start1=i; start2=j; while(a[start1]==b[start2] && start1<a.length() && start2<b.length()) { start1++; start2++; count++; } if(count>Max) { start = i; Max = count; } count=0; } } //保存字符串 s=new string[Max+1]; for(int i=0; i<Max; i++) { s[i]=a[i+start]; } s[Max]='\0'; return Max;}int main(){ string str1,str2,*str; cin>>str1>>str2; //此题输入------------- //getline(cin,str1); //getline(cin,str2); int length = Maxsubstr(str1,str2,str); for(int i=0; i<length; i++) { cout<<str[i]; } cout<<endl; return 0;}
如果你看到这里觉得暴力方法太low
Low。。。。
哎,那就聊聊动态规划版的经典问题《最长公共子串(序列)》
子串是连续的,子序列可以是不连续的。
状态转移方程:
符号约定,C1是S1的最右侧字符,C2是S2的最右侧字符,S1‘是从S1中去除C1的部分,S2’是从S2中去除C2的部分。
LCS(S1,S2)等于下列3项的最大者:
(1)LCS(S1,S2
′ )(2)LCS(S1
′ ,S2)(3)LCS(S1
′ ,S2’)–如果C1不等于C2; LCS(S1′ ,S2′ )+C1 —如果C1等于C2;
边界终止条件:如果S1和S2都是空串,则结果也是空串。
下面我们同样要构建一个矩阵来存储动态规划过程中子问题的解。这个矩阵中的每个数字代表了该行和该列之前的LCS的长度。与上面刚刚分析出的状态转移议程相对应,矩阵中每个格子里的数字应该这么填,它等于以下3项的最大值:
(1)上面一个格子里的数字
(2)左边一个格子里的数字
(3)左上角那个格子里的数字(如果 C1不等于C2); 左上角那个格子里的数字+1( 如果C1等于C2)
#include<iostream>#include<cstring>#include <vector>using namespace std;void SubSequence(vector<vector<string>> &flag,string str1, string str2,int i,int j);void display(int *result,string str1,string str2);void initialVector(vector<vector<string>> &vectorAll,int len){ for(int i=0; i<len; ++i) { vector<string> temp; vectorAll.push_back(temp); }}int lcs_string(string str1, string str2){ int len1 = str1.length(); int len2 = str2.length(); int result = 0; //记录最长公共子串长度 int c[len1+1][len2+1] ; int endPos = -1; for (int i = 0; i <= len1; i++) { for( int j = 0; j <= len2; j++) { if(i == 0 || j == 0) { c[i][j] = 0; } else if (str1.at(i-1) == str2.at(j-1)) { c[i][j] = c[i-1][j-1] + 1; result = max(c[i][j], result); if(result==c[i][j]) endPos = i;//记录最后一个点的位置 } else { c[i][j] = 0;//重新计数 } } } //print result string str=""; if(endPos<=len1) { str = str1.substr(endPos-result,result); } else { str = str2.substr(endPos-result,result); } cout<<"\n\nLongest Common Substring : "<<str<<endl; return result;}//对于最长公共子序列,只是在最后一个else里面放的是前两步的最大值int lcs_squence(string str1, string str2){ int len1 = str1.length(); int len2 = str2.length(); int c[len1+1][len2+1]; vector<vector<string>> flag; initialVector(flag,len1+1); for (int i = 0; i <= len1; i++) { for( int j = 0; j <= len2; j++) { if(i == 0 || j == 0) { c[i][j] = 0; flag[i].push_back("NULL"); } else if (str1.at(i-1) == str2.at(j-1)) { c[i][j] = c[i-1][j-1] + 1; flag[i].push_back("left_up"); } else if(c[i - 1][j]>=c[i][j - 1]) { c[i][j]=c[i - 1][j]; flag[i].push_back("left"); } else { c[i][j] = c[i][j - 1]; flag[i].push_back("up") ; } } } //display(&c[0][0],str1,str2); //输出数组 SubSequence(flag,str1,str2,str1.length(),str2.length()); //cout<<c[len1][len2]<<endl; return c[len1][len2];}void display(int *result,string str1,string str2){ int len1 = str1.length(); int len2 = str2.length(); //输出表头 for(int i=0; i<=len2; ++i) { cout<<"\t"<<str2[i]; } cout<<endl; //输出数组 for(int i=0; i<=len1; ++i) { cout<<str1[i]<<"\t"; for(int j=0; j<=len2; ++j) { cout<<*result<<"\t"; result++; } cout<<endl; }}//按照方向查找void SubSequence(vector<vector<string>> &flag,string str1, string str2,int i,int j){ if (i == 0 || j == 0) return; if (flag.at(i).at(j) == "left_up") { cout<<str2[j - 1]<<" ("<< i - 1<<" , "<< j - 1<<")"<<endl; //左前方 SubSequence(flag,str1,str2,i - 1, j - 1); } else { if (flag.at(i).at(j) == "up") { SubSequence(flag,str1,str2,i, j - 1); } else { SubSequence(flag,str1,str2,i - 1, j); } }}int main(){ string X = ""; string Y = ""; //输入 getline(cin,X); getline(cin,Y); cout<<"\nFirst string:\n"<<X<<endl; cout<<"\nSecond string:\n"<<Y<<endl; cout << "Length of Longest Common Substring is " << lcs_string(X, Y)<<endl; cout << "Length of Longest Common Subsequence is " << lcs_squence(X, Y)<<endl; return 0;}
参考引用
传送门 : 最长公共子序列
传送门 : 最长公共子序列(LCS)C++实现
传送门 : 最长公共子序列与最长公共子串
传送门 : 最长公共子序列。。
传送门 : 最长公共子序列。。大杂烩
- 公共字串计算(最长公共子串/序列)C++
- 最长公共子序列 && 最长公共字串
- 最长公共字串与公共子序列
- 最长公共字串 最长公共子序列问题
- 最长公共子序列和最长公共字串总结
- 最长公共字串与最长公共子序列
- 最长公共字串和最长公共子序列
- DP---最长公共子序列&最长公共字串
- 华为OJ 公共字串计算&&查找两个字符串a,b中的最长公共子串
- 动态规划之最长公共子序列和最长公共字串,最大子序列和
- 动态规划-最长公共子序列计算
- 整理:最长公共子串及最长公共子序列
- 最长公共子串和最长公共子序列
- 最长公共子序列和最长公共子串
- 最长公共子序列&最长公共子串
- 最长公共子序列 与 最长公共子串
- 最长公共子串 & 最长公共子序列
- 最长公共子序列和最长公共子串
- 数据库的设计
- Java SE Development Kit 8 Downloads
- 网上的ASP+Html如何配置运行啊?
- iOS 对源代码进行混淆和加密
- ES6中export及export default的区别
- 公共字串计算(最长公共子串/序列)C++
- 忘记mysql root密码解决办法
- 客户端发送Json数据问题
- 【高分求助】如何实现对某一字段的累加更新?求助各位达人,谢谢!
- i获取MAC,IMEI
- Android位置定位思路求助
- 回溯法
- 安卓复习之旅—单例模式
- iOS中使用Bugly定位收集真机崩溃日志信息