代码之家  ›  专栏  ›  技术社区  ›  Snowman

查找最大公共子序列

  •  1
  • Snowman  · 技术社区  · 15 年前

    我有以下代码,由于某些原因无法正常工作,我正在尝试解决:

    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")); 
    

    我得到一个索引

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

    3 回复  |  直到 15 年前
        1
  •  6
  •   TofuBeer    15 年前

    其中一部分似乎是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);
        }
    }
    
        2
  •  3
  •   thejh    15 年前
    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;
    }
    
        3
  •  0
  •   paulmurray    15 年前
    char[] a=new char[gene1.length()];
    a=gene1.toCharArray();
    

    嗯。你在第一行分配的数组怎么了?