找到最大公共子序列

发布于 2024-10-01 01:41:47 字数 788 浏览 4 评论 0原文

我有以下代码,由于我试图找出的某种原因,该代码无法正常工作:

public static int score(String gene1, String gene2){
    char[] a=new char[gene1.length()];
    char[] b=new char[gene2.length()];
    a=gene1.toCharArray();
    b=gene2.toCharArray();
    return score(a, b, 0,0);
}

private static int score(char[] a, char[] b, int i, int j){
    if(a[i]=='\0' || b[j]=='\0')
        return 0;
    else if (a[i]==b[j])
        return 1+score(a, b, i+1, j+1);
    else 
        return max(score(a, b,i+1, j),score(a, b, i, j+1));
}

private static int max (int a, int b){
    if (a<b) return b;
    else return a;
}

这是失败的地方:

assertEquals(2, GeneAnalysis.score("ACGT","AC")); 

我收到 IndexOutofBoundsError

有什么想法吗?另外,在提供帮助时,请不要更改方法参数。他们应该是这样的。

I have the following code, which does not work correctly for some reason that I am trying to figure out:

public static int score(String gene1, String gene2){
    char[] a=new char[gene1.length()];
    char[] b=new char[gene2.length()];
    a=gene1.toCharArray();
    b=gene2.toCharArray();
    return score(a, b, 0,0);
}

private static int score(char[] a, char[] b, int i, int j){
    if(a[i]=='\0' || b[j]=='\0')
        return 0;
    else if (a[i]==b[j])
        return 1+score(a, b, i+1, j+1);
    else 
        return max(score(a, b,i+1, j),score(a, b, i, j+1));
}

private static int max (int a, int b){
    if (a<b) return b;
    else return a;
}

Here is where it fails:

assertEquals(2, GeneAnalysis.score("ACGT","AC")); 

I get an IndexOutofBoundsError

Any ideas? Also, when offering help, please do not change method parameters. They are supposed to be the way they are.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

翻了热茶 2024-10-08 01:41:47

部分原因似乎是 C 和 Java 之间的混淆......

if(a[i]=='\0' || b[j]=='\0')
        return 0;

C 对于字符串有一个空终止符,而 Java 没有。相反,要检查 Java 数组的末尾,您将需要使用 .length 属性...类似于:

   if(i >= a.length || j >= b.length) 

根据注释进行编辑。

真的,你应该就此提出一个单独的问题......但这里是它是如何工作的。首先,您使用递归,是的,这是一个棘手的概念。维基百科可能可以帮助您了解递归的基础知识。

下面的代码更接近我的编写方式,其中的注释显示了事情发生的顺序:

public class Main
{
    public static void main(String[] args)
    {
        final int value;

        value = score("ACGT", "AC");
        System.out.println(value);
    }

    public static int score(final String gene1,
                            final String gene2)
    {
        final char[] a;
        final char[] b;
        final int    s;

        a = gene1.toCharArray();
        b = gene2.toCharArray();
        s = score(a, b, 0, 0);

        return (s);
    }

    private static int score(final char[] a,
                             final char[] b,
                             final int    idxA,
                             final int    idxB)
    {
        final int value;

        // for all calls: a.length == 4 and b.length == 2
        // first call:  idxA == 0 and idxB == 0 - false || false == false
        // second call: idxA == 1 and idxB == 1 - false || false == false
        // third call:  idxA == 2 and idxB == 2 - false || true  == true      
        if(idxA >= a.length || idxB >= b.length)
        {
            // third call: will return 0            
            value = 0;
        }
        // first call:  a[idxA] == A and b[idxB] == A - true
        // second call: a[idxB] == C and b[idxB] == C - true 
        else if(a[idxA] == b[idxB])
        {
            // this is recursion
            // first call:  1 + score(a, b, 1, 1)
            // second call: 1 + score(a, b, 2, 2)

            // after the third call the call stack starts unwinding
            // second call: 1 + 0 == 1
            // first call:  1 + 1 == 2
            value = 1 + score(a, b, idxA + 1, idxB + 1);
        }
        else
        {
            final int x;
            final int y;

            x = score(a, b, idxA + 1, idxB);
            y = score(a, b, idxB,     idxB + 1);
            value = max(x, y);
        }

        // third call:  0
        // second call: 1
        // first call:  2
        return (value);
    }

    // Can you use Math.max(int, int) instad?
    private static int max(final int x, final int y)
    {
        final int value;

        if(x < y)
        {
            value = y;
        }
        else
        {
            value = x;
        }

        return (value);
    }
}

Part of this seems to be a confusion between C and Java....

if(a[i]=='\0' || b[j]=='\0')
        return 0;

C has a null terminator for strings, Java does not. Instead to check for the end of a Java array you will need to use the .length attribute... something like:

   if(i >= a.length || j >= b.length) 

Edit based on comment.

Really, you should ask a separate question on this... but here is a stab at how it works. First off you are using recursion, which, yes, is a tricky concept. Wikipedia probably can help you with the basics of recursion.

Here is the code closer to how I would write it, with comments showing you the order that things occur in:

public class Main
{
    public static void main(String[] args)
    {
        final int value;

        value = score("ACGT", "AC");
        System.out.println(value);
    }

    public static int score(final String gene1,
                            final String gene2)
    {
        final char[] a;
        final char[] b;
        final int    s;

        a = gene1.toCharArray();
        b = gene2.toCharArray();
        s = score(a, b, 0, 0);

        return (s);
    }

    private static int score(final char[] a,
                             final char[] b,
                             final int    idxA,
                             final int    idxB)
    {
        final int value;

        // for all calls: a.length == 4 and b.length == 2
        // first call:  idxA == 0 and idxB == 0 - false || false == false
        // second call: idxA == 1 and idxB == 1 - false || false == false
        // third call:  idxA == 2 and idxB == 2 - false || true  == true      
        if(idxA >= a.length || idxB >= b.length)
        {
            // third call: will return 0            
            value = 0;
        }
        // first call:  a[idxA] == A and b[idxB] == A - true
        // second call: a[idxB] == C and b[idxB] == C - true 
        else if(a[idxA] == b[idxB])
        {
            // this is recursion
            // first call:  1 + score(a, b, 1, 1)
            // second call: 1 + score(a, b, 2, 2)

            // after the third call the call stack starts unwinding
            // second call: 1 + 0 == 1
            // first call:  1 + 1 == 2
            value = 1 + score(a, b, idxA + 1, idxB + 1);
        }
        else
        {
            final int x;
            final int y;

            x = score(a, b, idxA + 1, idxB);
            y = score(a, b, idxB,     idxB + 1);
            value = max(x, y);
        }

        // third call:  0
        // second call: 1
        // first call:  2
        return (value);
    }

    // Can you use Math.max(int, int) instad?
    private static int max(final int x, final int y)
    {
        final int value;

        if(x < y)
        {
            value = y;
        }
        else
        {
            value = x;
        }

        return (value);
    }
}
2024-10-08 01:41:47
public static int score(String gene1, String gene2){
    char[] a=gene1.toCharArray();//assign it directly
    char[] b=gene2.toCharArray();
    return score(a, b, 0, 0);
}

private static int score(char[] a, char[] b, int i, int j) {
    //check for end using length, java doesn't use that nullbyte-stuff for it
    //this caused the failure
    if(i==a.length || j==b.length) {
        return 0;
    } else if (a[i]==b[j]) {
        return 1+score(a, b, i+1, j+1);
    } else {
        return max(score(a, b, i+1, j), score(a, b, i, j+1));
    }
}

private static int max (int a, int b){
    if (a<b) return b;
    return a;
}
public static int score(String gene1, String gene2){
    char[] a=gene1.toCharArray();//assign it directly
    char[] b=gene2.toCharArray();
    return score(a, b, 0, 0);
}

private static int score(char[] a, char[] b, int i, int j) {
    //check for end using length, java doesn't use that nullbyte-stuff for it
    //this caused the failure
    if(i==a.length || j==b.length) {
        return 0;
    } else if (a[i]==b[j]) {
        return 1+score(a, b, i+1, j+1);
    } else {
        return max(score(a, b, i+1, j), score(a, b, i, j+1));
    }
}

private static int max (int a, int b){
    if (a<b) return b;
    return a;
}
彩虹直至黑白 2024-10-08 01:41:47
char[] a=new char[gene1.length()];
a=gene1.toCharArray();

唔。您在第一行中分配的数组会发生什么情况?

char[] a=new char[gene1.length()];
a=gene1.toCharArray();

Hmm. What happens to the array that you allocated in that first line?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文