dqzow3859 2013-11-22 13:13
浏览 128
已采纳

Go:打印结果数组的最长公共子序列

I have implemented Longest Common Subsequence algorithm and getting the right answer for longest but cannot figure out the way to print out what makes up the longest common subsequence.

That is, I succeeded to get the length of longest commond subsequence array but I want to print out the longest subsequence.

The Playground for this code is here

http://play.golang.org/p/0sKb_OARnf

/*
X = BDCABA
Y = ABCBDAB => Longest Comman Subsequence is B C B

Dynamic Programming method : O ( n )
*/

package main
import "fmt"

func Max(more ...int) int {
  max_num := more[0]
  for _, elem := range more {
    if max_num < elem {
      max_num = elem
    }
  }
  return max_num
}

func Longest(str1, str2 string) int {
  len1 := len(str1)
  len2 := len(str2)

  //in C++,
  //int tab[m + 1][n + 1];
  //tab := make([][100]int, len1+1)

  tab := make([][]int, len1+1)
  for i := range tab {
    tab[i] = make([]int, len2+1)
  }

  i, j := 0, 0
  for i = 0; i <= len1; i++ {
    for j = 0; j <= len2; j++ {
      if i == 0 || j == 0 {
        tab[i][j] = 0
      } else if str1[i-1] == str2[j-1] {
        tab[i][j] = tab[i-1][j-1] + 1
        if i < len1 {
          fmt.Printf("%c", str1[i])
        }
      } else {
        tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
      }
    }
  }
  fmt.Println()
  return tab[len1][len2]
}

func main() {
  str1 := "AGGTABTABTABTAB"
  str2 := "GXTXAYBTABTABTAB"
  fmt.Println(Longest(str1, str2))
  //Actual Longest Common Subsequence: GTABTABTABTAB
  //GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
  //13

  str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
  str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
  fmt.Println(Longest(str3, str4))
  //Actual Longest Common Subsequence: ?
  //GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
  //14
}

When I try to print out the subsequence when the tab gets updates, the outcome is duplicate. I want to print out something like "GTABTABTABTAB" for the str1 and str2

Thanks in advance.

  • 写回答

1条回答 默认 最新

  • dongshi1188 2013-11-22 14:38
    关注

    EDIT: It seems that I jumped the gun on answering this. On the Wikipedia page for Longest Common Subsequnce they give the pseudocode for printing out the LCS once it has been calculated. I'll put an implementation in go up here as soon as I have time for it.

    Old invalid answer

    You are forgetting to move along from a character once you have registered it as part of the subsequence.

    The code below should work. Look at the two lines right after the fmt.Printf("%c", srt1[i]) line.

    playground link

    /*
    X = BDCABA
    Y = ABCBDAB => Longest Comman Subsequence is B C B
    
    Dynamic Programming method : O ( n )
    */
    
    package main
    
    import "fmt"
    
    func Max(more ...int) int {
        max_num := more[0]
         for _, elem := range more {
            if max_num < elem {
                max_num = elem
            }
        }
        return max_num
    }
    
    func Longest(str1, str2 string) int {
        len1 := len(str1)
        len2 := len(str2)
    
        //in C++,
        //int tab[m + 1][n + 1];
        //tab := make([][100]int, len1+1)
    
        tab := make([][]int, len1+1)
        for i := range tab {
            tab[i] = make([]int, len2+1)
        }
    
        i, j := 0, 0
        for i = 0; i <= len1; i++ {
            for j = 0; j <= len2; j++ {
                if i == 0 || j == 0 {
                    tab[i][j] = 0
                } else if str1[i-1] == str2[j-1] {
                    tab[i][j] = tab[i-1][j-1] + 1
                    if i < len1 {
                        fmt.Printf("%c", str1[i])
                                                //Move on the the next character in both sequences
                        i++
                        j++
                    }
                } else {
                    tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
                }
            }
        }
        fmt.Println()
        return tab[len1][len2]
    }
    
    func main() {
        str1 := "AGGTABTABTABTAB"
        str2 := "GXTXAYBTABTABTAB"
        fmt.Println(Longest(str1, str2))
        //Actual Longest Common Subsequence: GTABTABTABTAB
        //GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
        //13
    
        str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
        str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
        fmt.Println(Longest(str3, str4))
        //Actual Longest Common Subsequence: ?
         //GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
        //14
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料