我正在学习最长的常见子序列,使用这些算法:
公共类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;
......
}
我现在迷失了。任何人都可以帮助我吗?
答案 0 :(得分:3)
我会使用字符串而不是处理单个字符来解决这个问题:
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()
比看起来更强大。
答案 1 :(得分:0)
如果
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来比较不是==
答案 2 :(得分:0)
import java.util.Scanner; class Main {
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));
}
}
} class Sub {
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;
}
}
答案 3 :(得分:0)
您使用的是矩阵方法,
就我个人而言,我认为这种方法更具脚本性,而动态编程和记忆的本质却落伍了。当我们更依赖脚本方法而不是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