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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/simon_world/article/details/40656099

输出所有最长公用子序列的实现(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]);
		}
	}
}


猜你喜欢

转载自blog.csdn.net/simon_world/article/details/40656099