[英]Find longest common subsequence of 2 String?
我正在学习最长的公共子序列,使用这些算法:
公开课 LCS {
static int[][] E;
static int[][] S;
static int D;
static int T;
static int L;
public static void LCS_cost(String X,String Y)
{
int m = X.length();
int n = Y.length();
E = new int[m][n];
S = new int[m][n];
for(int i=0;i<m;i++){
E[i][0] = 0;
}
for(int j=0;j<n;j++){
E[0][j] = 0;
}
for(int i=1;i<m+1;i++){
for(int j=1;j<n+1;j++){
if(X.charAt(i) == Y.charAt(j)){
E[i][j] = E[i-1][j-1]+1;
D = E[i-1][j-1]+1;
S[i][j] = D;//Diagonal Direction
}
else if (E[i-1][j]>=E[i][j-1]){
E[i][j] = E[i-1][j];
T = E[i-1][j];
S[i][j] = T;//TOP
}
else
E[i][j] = E[i][j-1];
L = E[i][j-1];
S[i][j] = L;//Left
}
}
}
public static void Backtrack(int[][] S,String X,String Y){
int row = X.length();
int col = Y.length();
while (row > 0 || col > 0){
if (S[row][col] == D){
System.out.print(X.charAt(row));
row--;
col--;
}
else if (S[row][col] == T){
row--;
}
else
col--;
}
}
public static void main(String[] args) {
new LCS();
LCS_cost("SCHOOL","SPOOL");
Backtrack(S,"SCHOOL", "SPOOL");
}
}
但是程序返回一个 ErrorCharAt(Unknow Source) 并且没有做任何事情。
我正在努力改变
for(int i=1;i<m+1;i++){
for(int j=1;j<n+1;j++){
到
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
结果是这一行 IndexOutofBoud
if (S[row][col] == D){
....
}
此外,如果我将int i和j更改为 0,则下面的 E 将是索引 -1 和错误
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(X.charAt(i) == Y.charAt(j)){
E[i][j] = E[i-1][i-1]+1;
......
}
我现在迷路了。有人能帮帮我吗?
我会使用字符串而不是处理单个字符来解决这个问题:
String findLCS(String str1, String str2) {
int longest = 0;
String longestSubstring = "";
for (int i=0; i < str1.length(); ++i) {
for (int j=i+1; j <= str1.length(); ++j) {
String substring = str1.substring(i, j);
if (str2.contains(substring) && substring.length() > longest) {
longest = substring.length();
longestSubstring = substring;
}
}
}
return longestSubstring;
}
如您所见,使用String.contains()
比看起来更强大。
如果
int m = X.length();
然后
for(int i=1;i<m+1;i++){
...
if(X.charAt(i) ....
将抛出错误,因为 Java 数组是基于零的
还有如果
int row = X.length();
int col = Y.length();
if (S[row][col] == D){
会抛出错误
另外,使用 String.equals 比较字符串而不是==
导入 java.util.Scanner; 类主要{
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
Sub s=new Sub();
int t=Integer.parseInt(sc.nextLine());
for(int i=1;i<=t;i++)
{
String a=sc.next();
String b=sc.next();
System.out.println("Case "+i+": "+s.subString(a, b));
}
}
} 类子 {
public static int subString (String a,String b)
{
int max=0;
int m=a.length();
int n=b.length();
int dp[][]=new int [m][n];
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(a.charAt(i)==b.charAt(j))
{
if(i==0||j==0)
{
dp[i][j]=1;
}
else
dp[i][j]=dp[i-1][j-1]+1;
}
if(max<dp[i][j])
max=dp[i][j];
}
}
return max;
}
}
您正在使用矩阵方法,我们,
我个人觉得这种方法更像脚本,动态规划和记忆的本质在它背后脱落。 当我们更多地依赖脚本方法而不是 DP 和备忘录的纯逻辑时——我们更容易出错或可能在两者之间迷失……
我没有使用矩阵方法,而是使用动态规划和记忆来将 LCS 演示为 -
package com.company.dynamicProgramming;
import java.util.HashMap;
import java.util.Map;
public class LongestCommonSubsequnce {
public static void main(String ...args){
String s1 = "SCHOOL";
String s2 = "SPOOL";
System.out.println(new StringBuilder(findLcs(s1, s2, new HashMap<>())).reverse());
}
static String findLcs(String s1, String s2, Map<String, String> memo){
//check if lcs is already processed in memo for s1 & s2
String lcs = memo.get(s1+"-"+s2);
if(lcs != null){
return lcs;
}
if (s1.substring(s1.length()-1).equals(s2.substring(s2.length()-1))){
lcs = s1.substring(s1.length()-1);
if(s1.length()>1 && s2.length()>1){
lcs = lcs + findLcs(s1.substring(0, s1.length()-1), s2.substring(0, s2.length()-1), memo);
memo.put(s1.substring(0, s1.length()-1)+ "-" + s2.substring(0, s2.length()-1), lcs);
}
else {
memo.put(s1+"-"+s1, lcs);
}
return lcs;
}else {
String lcs1="";
String lcs2="";
if(s1.length()>1 && s2.length()>1){
lcs1 = findLcs(s1.substring(0, s1.length()-1), s2, memo);
memo.put(s1.substring(0, s1.length()-1)+"-"+s2, lcs1);
lcs2 = findLcs(s1,s2.substring(0, s2.length()-1),memo);
memo.put(s1 +"-"+s2.substring(0, s2.length()-1), lcs2);
}
else if(s1.length()>1){
lcs1 = findLcs(s1.substring(0, s1.length()-1), s2, memo);
memo.put(s1.substring(0, s1.length()-1)+"-"+s2, lcs1);
}
else if(s2.length()>1){
lcs2 = findLcs(s1,s2.substring(0, s2.length()-1),memo);
memo.put(s1 +"-"+s2.substring(0, s2.length()-1), lcs2);
}else {
memo.put(s1+"-"+s2,"");
}
if(lcs1.length() >= lcs2.length()){
return lcs1;
}else {
return lcs2;
}
}
}
}
运行这段代码,结果是——
SOOL
Process finished with exit code 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.