#include <iostream>using namespace std;/*思路:假设两个字符串str1和str2,长度分别为m和n,则构建一个m*n的矩阵matrix,matrix[i][j]==1表示字符串str1中第i个字符与str2中第j个字符相等,为0则不相等。统计矩阵matrix中每条斜线上1的连续最大个数就是str1和str2中公共连续子串的最大长度*//*例如:str1: abcde str2: abgdematrix = [ 1 0 0 0 00 1 0 0 00 0 0 0 00 0 0 1 00 0 0 0 1 ]斜线上连续的1的最大个数为2,所以最长公共连续子串长度为2*/intmain(){charstr1[51];charstr2[51];intleng, maxleng=0;cin.getline(str1, 51);cin.getline(str2, 51);intmatrix[50][50] = { 0}; //构建初始矩阵matrixfor(inti = 0; str1[i] != '\0'; i++){for(intj = 0; str2[j] != '\0'; j++){if(str1[i] == str2[j])matrix[i][j] = 1; //如果str1中第i个字符与str2中第j个字符相等,则为1}}//循环统计每条斜线上的连续1的个数for(inti = 0; str1[i]!='\0'; i++){for(intj = 0; str2[j]!='\0'; j++){leng = 0;intm = i;intn = j;while(matrix[m++][n++] == 1) //判断其右下角位置是否为1leng++;if(maxleng < leng)maxleng = leng;}}cout << maxleng;return0;}
#include <stdio.h>
#include <string.h>
#define N 50
int main(){
char s1[N],s2[N];
int dp[N][N],i,j,max_len=0;
gets(s1);
gets(s2);
for(i=0;i<strlen(s1);i++){
for(j=0;j<strlen(s2);j++){
if(s1[i]==s2[j]){
if(i>0&&j>0){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=1;
}
if(max_len<dp[i][j]){
max_len=dp[i][j];
}
}
}
}
printf("%d\n",max_len);
return 0;
}
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
String str1 = scanner.nextLine();
String str2 = scanner.nextLine();
scanner.close();
//字符串的长度
int n1 = str1.length();
int n2 = str2.length();
//边界情况
if(n1 < 1 || n2 < 1)
{
System.out.println(0);
return;
}
//利用空间存储两个串的比较结果,空间换时间
int temp[][] = new int[n1][n2];
//表示最长的公共字串的变量
int longest = 0;
char[] char1 = str1.toCharArray();
char[] char2 = str2.toCharArray();
//初始化数组temp
for(int i = 0; i < n1; i++)
{
for(int j = 0;j <n2;j++)
{
temp[i][j] = 0;
}
}
//初始化第一行,初始化第一列,因为状态转移公式:item[i][j]=1 +item[i-1][j-1]
for(int i = 0;i < n1;i++)
{
if(char1[i] == char2[0])
temp[i][0] = 1;
}
for(int i = 0;i < n2;i++)
{
if(char1[0] == char2[i])
temp[0][i] = 1;
}
//利用状态转移方程进行填充temp二维数组
for(int i = 1; i < n1;i++)
{
for(int j = 1; j<n2;j++)
{
if (char1[i] == char2[j])
{
temp[i][j] = temp[i-1][j-1] +1;
}
}
}
for(int i = 0; i < n1;i++)
{
for(int j = 0; j<n2;j++)
{
if(temp[i][j] > longest)
longest = temp[i][j];
}
}
System.out.println(longest);
}
}
#include<iostream>
#include <string.h>
using namespace std;
int getMax(int a,int b)
{
return a>b?a:b;
}
int main()
{
int ret = 0;
char ch1[50];
char ch2[50];
cin.getline(ch1,50);
cin.getline(ch2,50);
for(int i = 0;i<strlen(ch1);i++)
{
int n = 0;
for(int j =0;j<strlen(ch2);j++)
{
if(ch1[i+n] == ch2[j])
{
n++;
ret = getMax(ret,n);
continue;
}
else
n=0;
}
}
cout << ret;
} 二维动态规划,改成一维了,假设已经找到最长公共子串,并且子串最后一个字符对应于
s1、s2的第i、j个字符,那么dp[i][j]就是最终结果。
dp[i][j]表示以s1第i个字符、s2第j个字符为结尾的最长公共子串长度,
dp[i][j] = dp[i-1][j-1] + k(if(s[i] == s[j],k = 1否则k = 0)
缩小空间复杂度的一种简单方法是dp[i%2][j] = dp[(i-1)%2][j],直接写成二维的程序
然后无脑加上模运算
import java.util.*;
public class Main{
public static void main(String[] arg){
Scanner sc = new Scanner(System.in);
char[] s1 = sc.nextLine().toCharArray(), s2 = sc.nextLine().toCharArray();
int max = 0;
int[] dp = new int[s2.length+1];
dp[0] = 0;
for(int i = 0; i < s1.length; ++i){
for(int j = dp.length-1; j >= 1; --j){
if(s1[i] == s2[j-1]) dp[j] = dp[j-1] + 1;
else dp[j] = 0;
if(dp[j]> max) max = dp[j];
}
}
System.out.println(max);
}
} a=raw_input()b=raw_input()ct=[]s=0fl=0iflen(a)==1and len(b)!=1:fl=1fori in b:ifa==i:print 1else:print 0iflen(b)==1:fl=1fori in a:ifb==i:print 1else:print 0fori in range(len(a)-1):forj in range(len(b)-1):ifa[i]==b[j] and a[i+1]==b[j+1]:s=s+1breakelif a[i]==b[j]:ct.append(s)s=0ct.append(s)ifmax(ct)!=0:print max(ct)+1else:iffl==0:print 0
}
import java.util.Scanner;
public class LongestSubstring {
public static void main (String args[]){
Scanner scanner=new Scanner(System.in);
String str1=scanner.nextLine();
String str2=scanner.nextLine();
int max=0;
System.out.print(longestSubstring(str1,str2));
}
public static int longestSubstring(String str1,String str2){
if(str1.length()==0||str2.length()==0) return 0;
int max=0;
for(int i=1;i<=str1.length();i++){
for(int j=i;j<=str1.length();j++){
StringBuffer sb1=new StringBuffer(str1.substring(i-1,j));
System.out.println(sb1);
if(str2.contains(sb1)){
if(sb1.length()>=max) max=sb1.length();
}
}
}
return max;
}
import java.util.Scanner;
public class Main {
public int findLength(String s1, String s2) {
char[] A = s1.toCharArray();
char[] B = s2.toCharArray();
int n = A.length;
int m = B.length;
int[][] dp = new int[n + 1][m + 1];
int res = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (A[i - 1] == B[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
res = Math.max(res, dp[i][j]);
}
}
}
return res;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
String s1=cin.nextLine();
String s2 = cin.nextLine();
System.out.println(new Main().findLength(s1,s2));
}
}
/*
abcde
abgde
2
asdfas
werasdfaswer
6
*/ import sys try: while True: a = input() b = input() lm = len(a) ln = len(b) if lm >= ln: m = b n = a l = ln else: m = a n = b l = lm x = 0 y = 0 for i in range(l): for j in range(l,i,-1): if m[i:j] in n: y = len(m[i:j]) break if x < y: x = y print(x) except: pass
#include <iostream>
#include <cstring>
using namespace std;
#define N 50
int main(){
char s1[N]; char s2[N];
cin.getline(s1, N);
cin.getline(s2, N);
int a[N][N];
int max=0;
for(int i=0;i<strlen(s1);i++){
for(int j=0;j<strlen(s2);j++){
a[i][j]=0;
if(s1[i]==s2[j]){
if(i>0&&j>0)a[i][j]=a[i-1][j-1]+1;
else a[i][j]=1;
max=max>a[i][j]?max:a[i][j]; } } } cout<<max<<endl;
return 0;
} list1=list(input()) list2=list(input()) list1_tmp=[] list2_tmp=[] for i in range(len(list1)): tmp="" for j in range(i,len(list1)): tmp=tmp+list1[j] list1_tmp.append(tmp) for i in range(len(list2)): tmp="" for j in range(i,len(list2)): tmp=tmp+list2[j] list2_tmp.append(tmp) L=[] for i in list1_tmp: if i in list2_tmp: if len(i)>len(L): L=i print(len(L))Python暴力枚举子集寻找最长公共子集
import sys lines1 = raw_input() line2 = raw_input() lines = [lines1,line2] length1 = len(lines[0]) length2 = len(lines[1]) matrix = [[0]* length2 for i in range(length1)] for i in range(len(lines[0])): for j in range(len(lines[1])): if lines[0][i] == lines[1][j]: matrix[i][j] = 1 maxCount = 0 for i in range(len(lines[0])): for j in range(len(lines[1])): count = 0 while i < len(lines[0]) and j < len(lines[1]) and matrix[i][j] == 1: count += 1 i += 1 j += 1 maxCount = max(maxCount,count) print maxCount
#include <iostream> #include <string.h> using namespace std; int dp[50][50]={0}; int LCS2(const string &a,const string &b,int n,int m) { memset(dp[0],0,sizeof(dp[0])); for(int i=0;i<50;i++) { dp[i][0]=0; } int max=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i-1]==b[j-1]) { dp[i][j] = dp[i-1][j-1]+1; if(dp[i][j]>max) max = dp[i][j]; } else { dp[i][j] = 0; } } } return max; } int main() { string a,b; while(getline(cin,a)) { getline(cin,b); cout<<LCS2(a,b,a.length(),b.length())<<endl; } return 0; }
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int findmax(string a,string b,int m,int n){
int k=0,l=0;
for(int i=0;i<a.length()-m && i<b.length()-n;i++){
if(a[m+i]==b[n+i]) k++;
else{
if(k>l) l=k;
k=0;
return l;
}
}
return k;
}
int main(int argc, const char * argv[]) {
string a,b;
getline(cin,a);
getline(cin,b);
int m=0,n=0;
string temp;
if(a.length()>b.length()){
temp = a;
a = b;
b = temp;
}
for(int i =0;i<a.length();i++){
for(int j=0;j<b.length();j++){
if(a[i]==b[j]){
m = findmax(a, b, i, j);
if(m>n){
n=m;
}
}
}
}
cout<<n;
return 0;
}
public static int maxLenghtOfPublicString(String str1, String str2) {
if (str1.length() == 0 || str2.length() == 0) {
return 0;
}
int maxLength = 0;
int len1 = str1.length();
int len2 = str2.length();
int[] matrix = new int [len1 * len2];
int i, j;
// 计算数组
for (i = 0; i < len1; i++) {
String s1 = str1.substring(i, i + 1);
for (j = 0; j < len2; j++) {
String s2 = str2.substring(j, j + 1);
int index = i + j * len1;
int value = s1.equals(s2) ? 1 : 0;
matrix[index] = value;
}
}
// 统计以i开头的第一个系列的斜线
String []tmpResult = new String[len1 + len2];
for (i = 0; i < len1; i++) {
int tmpI = i;
StringBuilder sb = new StringBuilder();
for (j = 0; j < len2 && tmpI < len1; j++, tmpI++) {
int index = tmpI + j * len1;
sb.append(matrix[index]);
}
int tmpResultIndex = i;
tmpResult[tmpResultIndex] = sb.toString();
}
// 统计以j开头的第一个系列的斜线
for (j = 0; j < len2; j++) {
int tmpJ = j;
StringBuilder sb = new StringBuilder();
for (i = 0; i < len1 && tmpJ < len2; i++, tmpJ ++) {
int index = i + tmpJ * len1;
sb.append(matrix[index]);
}
//
int tmpResultIndex = len1 + j;
tmpResult[tmpResultIndex] = sb.toString();
}
// 求最长连续子序列
for (i = 0; i < tmpResult.length; i++) {
int tmpMax = 0;
String tmpString = tmpResult[i];
for (j = 0; j < tmpString.length(); j++) {
int value = Integer.parseInt(tmpString.substring(j, j + 1));
if (value == 1) {
tmpMax++;
} else {
maxLength = Math.max(maxLength, tmpMax);
tmpMax = 0;
}
}
maxLength = Math.max(maxLength, tmpMax);
}
return maxLength;
}