由于最长公共子序列可以使用动态规划使用类似的方式来实现,这里就不做过多的阐述.
子序列和子串的区别就在于连续性的区别,前者可以离散,后者连续.
- 由于动态规划都需要实现一个生成table的函数,然后根据所得到的table去反向求得子串,依照这个思路就有了下面的代码:
// returns the longest length
func Lcs2(a, b []int) (int, [][]int, int, int) {
// 1. 根据 a, b生成s表
lenA, lenB := len(a), len(b)
s := TwoDimSlice(lenA+1, lenB+1)
res := 0
indexI := 0
indexJ := 0
for i := 0; i < lenA+1; i++ {
for j := 0; j < lenB+1; j++ {
if i == 0 || j == 0 {
s[i][j] = 0
continue
}
if a[i-1] != b[j-1] {
s[i][j] = 0
continue
}
if a[i-1] == b[j-1] {
s[i][j] = s[i-1][j-1] + 1
//res = max(res, s[i][j])
if s[i][j] > res {
res = s[i][j]
indexI = i
indexJ = j
}
continue
}
}
}
return res, s, indexI, indexJ
}
//创建一个尺寸为a , b的二维切片
func TwoDimSlice(a, b int) [][]int {
slice1 := make([][]int, a)
for i, _ := range slice1 {
//tmp := make([]int, b)
//sliceItem = append(sliceItem, tmp...)
slice1[i] = make([]int, b)
}
return slice1
}
// 根据所记录的最大长度的index 来返回最长的子串
func findStr(indexi int, target []int, longest int) string {
res := ""
for i := indexi - longest; i < + indexi; i++ {
res += strconv.Itoa(target[i])
}
return res
}
//这就是主要的三个函数 lcs2返回依次是 最长长度, s表, 最大值的横坐标, 最大值的纵坐标
// TwoDimSlice用来构造一个二维切片
// 第三个是用来查找相同的子串