java最长公共子序列算法_最长公共子序列 - dataCube的个人空间 - OSCHINA - 中文开源技术交流社区...

public class LongestCommonSubsequence3 {

public static void main(String[] args) {

LongestCommonSubsequence3 lcs = new LongestCommonSubsequence3();

System.out.println(lcs.compute("ABCBDAB","BDCABA"));

}

public static int compute(char[] str1, char[] str2)

{

int substringLength1 = str1.length;

int substringLength2 = str2.length;

// 构造二维数组记录子问题A[i]和B[j]的LCS的长度,默认初始化为0

int[][] chess = new int[substringLength1 + 1][substringLength2 + 1];

// 从从前到后,动态规划计算所有子问题。也可从前向后

for (int i = 1; i <= substringLength1; i++)

{

for (int j = 1; j <= substringLength2; j++)

{

if (str1[i - 1] == str2[j - 1])

chess[i][j] = chess[i - 1][j - 1] + 1;// 状态转移方程

else

chess[i][j] = Math.max(chess[i - 1][j], chess[i][j - 1]);// 状态转移方程

}

}

System.out.println("substring1:" + new String(str1));

System.out.println("substring2:" + new String(str2));

System.out.print("LCS:");

int i = str1.length, j = str2.length;

String temp = "";

while (i != 0 && j != 0)

{

if (str1[i - 1] == str2[j - 1])

{

temp += str1[i - 1];

i--;

j--;

}

else{

if (chess[i][j - 1] > chess[i - 1][j])

j--;

else

i--;

}

}

for (int k = temp.length() - 1; k >= 0; k--) {

System.out.print(temp.toCharArray()[k]);

}

System.out.println();

return chess[str1.length][str2.length];

}

public int compute(String str1, String str2)

{

return compute(str1.toCharArray(), str2.toCharArray());

}

}

//================

public class LongestCommonSubsequence2 {

public static void main(String[] args) {

LongestCommonSubsequence2 lcs = new LongestCommonSubsequence2();

System.out.println(lcs.compute("ABCBDAB","BDCABA"));

}

public static int compute(char[] str1, char[] str2)

{

int substringLength1 = str1.length;

int substringLength2 = str2.length;

// 构造二维数组记录子问题A[i]和B[j]的LCS的长度

int[][] opt = new int[substringLength1 + 1][substringLength2 + 1];

// 从后向前,动态规划计算所有子问题。也可从前到后。

for (int i = substringLength1 - 1; i >= 0; i--)

{

for (int j = substringLength2 - 1; j >= 0; j--)

{

if (str1[i] == str2[j])

opt[i][j] = opt[i + 1][j + 1] + 1;// 状态转移方程

else

opt[i][j] = Math.max(opt[i + 1][j], opt[i][j + 1]);// 状态转移方程

}

}

System.out.println("substring1:" + new String(str1));

System.out.println("substring2:" + new String(str2));

System.out.print("LCS:");

int i = 0, j = 0;

while (i < substringLength1 && j < substringLength2)

{

if (str1[i] == str2[j])

{

System.out.print(str1[i]);

i++;

j++;

}

else if (opt[i + 1][j] >= opt[i][j + 1])

i++;

else

j++;

}

System.out.println();

return opt[0][0];

}

public int compute(String str1, String str2)

{

return compute(str1.toCharArray(), str2.toCharArray());

}

}

//====================

package com.lifeibigdata.algorithms.string;

/**

* Created by lifei on 16/5/25.

*/

public class LongestCommonSubsequence {

public static void main(String[] args) {

char[] x = {' ','A','B','C','B','D','A','B'};

char[] y = {' ','B','D','C','A','B','A'};

LongestCommonSubsequence lcs = new LongestCommonSubsequence();

lcs.printLCS(lcs.lcsLength(x, y), x, x.length-1, y.length-1);

}

void printLCS(int[][] b,char[] x,int i,int j){

if(i == 0 || j == 0)

return;

if(b[i][j] == 1){

printLCS(b,x,i - 1,j - 1);

System.out.print(x[i] + "\t");

}else if(b[i][j] == 2)

printLCS(b,x,i - 1,j);

else

printLCS(b,x,i,j - 1);

}

int[][] lcsLength(char[] x,char[] y){

int m = x.length;

int n = y.length;

int i,j;

int[][] c = new int[m][n];

int[][] b = new int[m][n];

for(i = 1;i < m;i++)

c[i][0] = 0;

for(j = 0;j < n;j++)

c[0][j] = 0;

for(i = 1;i < m;i++)

for(j = 1;j < n;j++){

if(x[i] == y[j]){

c[i][j] = c[i - 1][j - 1] + 1;

b[i][j] = 1;

}

else if(c[i - 1][j] >= c[i][j - 1]){

c[i][j] = c[i - 1][j];

b[i][j] = 2;

}else{

c[i][j] = c[i][j - 1];

b[i][j] = 3;

}

}

return b;

}

}

/**

* 滚动数组只求大小,可以降低空间复杂度,时间复杂度不变

* 求全部的lcs,使用深搜或广搜

* 求有几个lcs,即只求lcs数目,计算有多少分支,即2的多少次方

*

*

*/

880c92b279e4aab02fd15ed46ee27817.png

c06a12d4ef70d575c6ad43087445eb44.png

d8342706fbe2768c0ee59478a28e4446.png

6ed35c8477afcf449bcd8fada446a02d.png

a54773c3aa62b3d716a243962384ad83.png

7701fd201d47a96314ebfc60d43c5e02.png

666fe1266ee5fec7820feefd78ca87c6.png

97f2921b95317b535fa7e429c9ac03b1.png

b12d91eb9e8a17e6d81668df36d5a753.png

2b8a452e3ab40dfb524287429047fb4d.png

03e09d3ca62e808324bfdd20a3c56bf1.png

93f7a0d6aa04d095b830af50c9602829.png

90cf7efdcbce22e5c2c0fe6b5f04d739.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值