您的位置:首页 > 其它

最长公共子序列&&最长公共子串

2016-08-16 20:16 155 查看

概念

前提:都是有2个字符串

最长公共子串:子串要求在原字符串中是连续的

最长公共子序列:子串要求在原字符串中不要求连续

最长公共子串

最长公共子串为最长公共子序列的子问题,要求下标序列是递增的,且每次递增的增量为1。采用动态规划解题时,主要体现在状态转移函数的不同。



package com.xianggen.algorithm;

import java.util.Scanner;

/**
* 最长公共子串
* @author xianggen
* @date 2016年8月21日 上午12:09:26
*/
public class LCStr {
public static void main(String[] args) {
String str1,str2;
Scanner scan=new Scanner(System.in);
while(scan.hasNext()){
str1=scan.nextLine();
str2=scan.nextLine();
String lcStr=lscStr(str1,str2);
System.out.println(lcStr);
}
scan.close();
}
/**
*
* @param str1
* @param str2
* @return
*/
public static String lscStr(String str1,String str2){
int len1,len2,maxLen=-1;
len1=str1.length();
len2=str2.length();
int x=0,y=0;
int[][] state=new int[len1+1][len2+1];
//第一个字符串,将第一列全置0,见图
for(int i=0;i<len1+1;i++)
state[i][0]=0;
//第二个字符串,将第一行全置0
for(int j=0;j<len2+1;j++)
state[0][j]=0;
for(int i=1;i<len1+1;i++){
for(int j=1;j<len2+1;j++){
if(str1.charAt(i-1)==str2.charAt(j-1))
state[i][j]=state[i-1][j-1]+1;
else
state[i][j]=0;
if(state[i][j]>maxLen){
maxLen=state[i][j];
x=i;
y=j;
}
}
}
int i=x-1,j=y-1;
while(i>=0&&j>=0){
if(str1.charAt(i)==str2.charAt(j)){
i--;
j--;
}else
break;
}
String commonStr=str1.substring(i+1,x);
return commonStr;
}
}


最长公共子序列

Longest Common Subsequence, LCS

引入状态转移方程:





/**
*
* @param str1
* @param str2
* @return
*/
public static String lscStr(String str1,String str2){
int len1,len2,maxLen=-1;
len1=str1.length();
len2=str2.length();
int[][] state=new int[len1+1][len2+1];
//第一个字符串,将第一列全置0,见图
for(int i=0;i<len1+1;i++)
state[i][0]=0;
//第二个字符串,将第一行全置0
for(int j=0;j<len2+1;j++)
state[0][j]=0;
for(int i=1;i<len1+1;i++){
for(int j=1;j<len2+1;j++){
if(str1.charAt(i-1)==str2.charAt(j-1))
state[i][j]=state[i-1][j-1]+1;
//上边值大于左边值
else if(state[i-1][j]>state[i][j-1])
state[i][j]=state[i-1][j];
else
state[i][j]=state[i][j-1];

if(state[i][j]>maxLen)
maxLen=state[i][j];
}
}
System.out.println("maxLen="+maxLen);
System.out.println("输出公共子序列:");
int i=len1,j=len2,k;
k=state[len1][len2];
char[] result=new char[k];
while(i>0&&j>0){
if(str1.charAt(i-1)==str2.charAt(j-1)){
result[--k]=str1.charAt(i-1);
i--;
j--;
}else if(state[i-1][j]<state[i][j-1])
j--;
else
i--;
}
String commonStr=String.valueOf(result);
return commonStr;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: