输出所有最长公用子序列的实现(Java)

来源:互联网 发布:sql case with 编辑:程序博客网 时间:2024/05/16 09:15

输出所有最长公用子序列的实现(Java)

前言:

最长公共子序列的算法是比较经典的,在算法导论给出的经典算法可以实现输出一条最长公共子序列。但是有多个最长公共子序列怎么办呢?其实也比较简单就是把那三种情况分为四种即可:斜向上、向左、向上、向左或向上。在搜索时遇到两个方向时,一直选择一个方向即可。这样做可以找到所有的最长公共子序列,但是会有重复,可以用set集去重即可。另外有一篇硕士论文是讲了一种基于这种思想的方法,借助了两个辅助栈。感兴趣的也可看看这个链接:http://www.docin.com/p-759517222.html
下面给出基本的输出最长公共子序列的Java实现。

代码实现:

package com.lcs;import java.util.Scanner;import java.util.TreeSet;public class Lcs {public StringBuffer X;public StringBuffer Y;public static int m;public static int n;public int len;public static int[][] b;public int[][] c;public String[] Log;public char[] lcs;public final int MAX = 100;public int CurLen;public static void main(String[] args) {Lcs lcs = new Lcs();lcs.search();}public void search() {while(true) {System.out.println("\n" + "请选择功能:");System.out.println("\n" + "1.寻找最长公共子序列");System.out.println("\n" + "2.结束");Scanner in = new Scanner(System.in);int choose = in.nextInt();switch(choose) {case 1:System.out.println("请输入序列X:");X = new StringBuffer(in.next());System.out.println("请输入序列Y:");Y = new StringBuffer(in.next());lcs_length();System.out.println("两序列的最长公共子序列为:");storeLCS(m,n,len);PrintLCS();X.setLength(0);Y.setLength(0);break;case 2:in.close();System.exit(0);break;default:in.close();System.exit(-1);}}}public void lcs_length() {m = X.length();n = Y.length();c = new int[m+1][n+1];b = new int[m+1][n+1];for(int i = 1; i <= m; i++) c[i][0] = 0;for(int j = 0; j <= n; j++) c[0][j] = 0;for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++) {if(X.charAt(i-1) == Y.charAt(j-1)){c[i][j] = c[i-1][j-1] + 1;b[i][j] = 0;} else if(c[i-1][j] > c[i][j-1]) {c[i][j] = c[i-1][j];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;}}lcs = new char[m+1];len = c[m][n];Log = new String[MAX];CurLen = 0;}public void storeLCS(int m,int n,int Len) {if(m == 0 || n == 0) {Log[CurLen] = new String(lcs);CurLen++;} else {if(b[m][n] == 0) {lcs[Len] = X.charAt(m-1);Len--;storeLCS(m-1,n-1,Len);} else if(b[m][n] == 3) {storeLCS(m,n-1,Len);} else if(b[m][n] == 1) {storeLCS(m-1,n,Len);} else {storeLCS(m,n-1,Len);storeLCS(m-1,n,Len);}}}public void PrintLCS() {TreeSet<String> tr = new TreeSet<String>();for(int i = 0; i < CurLen; i++) {tr.add(Log[i]);}String[] s2= new String[tr.size()];for(int i = 0; i < s2.length; i++) { s2[i]=tr.pollFirst();//从TreeSet中取出元素重新赋给数组 System.out.println(s2[i]);}}}


0 0