文心一言 VS 讯飞星火 VS chatgpt (205)-- 算法导论15.4 1题

一、求〈1,0,0,1,0,1,0,1〉和〈0,1,0,1,1,0,1,1,0〉的一个LCS。需要写代码的时候,请用go语言。

文心一言,代码正常运行:

在Go语言中,求两个序列的最长公共子序列(Longest Common Subsequence, LCS)可以使用动态规划(Dynamic Programming, DP)的方法。下面是一个Go语言实现的示例代码,用于找到给定两个序列的LCS:

package main  
  
import (  
	"fmt"  
)  
  
// lcsLength 计算两个序列的最长公共子序列的长度  
func lcsLength(X []int, Y []int) int {  
	m := len(X)  
	n := len(Y)  
  
	// 创建一个二维数组来保存子问题的解  
	L := make([][]int, m+1)  
	for i := range L {  
		L[i] = make([]int, n+1)  
	}  
  
	// 动态规划填充表格  
	for i := 1; i <= m; i++ {  
		for j := 1; j <= n; j++ {  
			if X[i-1] == Y[j-1] {  
				L[i][j] = L[i-1][j-1] + 1  
			} else {  
				L[i][j] = max(L[i-1][j], L[i][j-1])  
			}  
		}  
	}  
  
	// 返回LCS的长度  
	return L[m][n]  
}  
  
// max 返回两个整数中的较大值  
func max(a, b int) int {  
	if a > b {  
		return a  
	}  
	return b  
}  
  
// lcs 构造最长公共子序列  
func lcs(X []int, Y []int) []int {  
	m := len(X)  
	n := len(Y)  
  
	L := make([][]int, m+1)  
	for i := range L {  
		L[i] = make([]int, n+1)  
	}  
  
	// 填充L[][]数组  
	for i := 1; i <= m; i++ {  
		for j := 1; j <= n; j++ {  
			if X[i-1] == Y[j-1] {  
				L[i][j] = L[i-1][j-1] + 1  
			} else {  
				L[i][j] = max(L[i-1][j], L[i][j-1])  
			}  
		}  
	}  
  
	// 从L[][]数组回溯构造LCS  
	i, j := m, n  
	lcs := []int{}  
	for i > 0 && j > 0 {  
		if X[i-1] == Y[j-1] {  
			lcs = append([]int{X[i-1]}, lcs...)  
			i--  
			j--  
		} else if L[i-1][j] > L[i][j-1] {  
			i--  
		} else {  
			j--  
		}  
	}  
  
	return lcs  
}  
  
func main() {  
	X := []int{1, 0, 0, 1, 0, 1, 0, 1}  
	Y := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}  
  
	// 计算LCS的长度  
	length := lcsLength(X, Y)  
	fmt.Printf("Length of LCS is: %d\n", length)  
  
	// 构造LCS  
	lcsResult := lcs(X, Y)  
	fmt.Println("One LCS is:", lcsResult)  
}

这段代码定义了两个函数:lcsLength 用于计算LCS的长度,lcs 用于构造LCS本身。main 函数中初始化了两个序列 X 和 Y,并调用了这两个函数来展示LCS的长度和一个可能的LCS。

请注意,LCS可能不是唯一的,因为可能有多个具有相同长度的子序列满足条件。上述代码只返回了其中一个可能的LCS。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

讯飞星火,代码正常运行:

在Go语言中,我们可以使用动态规划的方法来求解两个序列的最长公共子序列。以下是一个简单的实现:

package main
import "fmt"

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func lcs(X []int, Y []int, m int, n int) int {
    L := make([][]int, m+1)
    for i := range L {
        L[i] = make([]int, n+1)
    }
    for i := 0; i <= m; i++ {
        for j := 0; j <= n; j++ {
            if i == 0 || j == 0 {
                L[i][j] = 0
            } else if X[i-1] == Y[j-1] {
                L[i][j] = L[i-1][j-1] + 1
            } else {
                L[i][j] = max(L[i-1][j], L[i][j-1])
            }
        }
    }
    return L[m][n]
}

func main() {
    X := []int{1, 0, 0, 1, 0, 1, 0, 1}
    Y := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}
    m := len(X)
    n := len(Y)
    fmt.Println("Length of LCS is", lcs(X, Y, m, n))
}

在这个代码中,我们首先定义了一个二维数组L,其中L[i][j]表示序列X的前i个元素和序列Y的前j个元素的最长公共子序列的长度。然后我们遍历这两个序列,如果当前的元素相同,那么最长公共子序列的长度就是前一个元素的最长公共子序列的长度加一;否则,最长公共子序列的长度就是去掉当前元素后的最长公共子序列的长度的最大值。最后,返回的就是L[m][n],即两个序列的最长公共子序列的长度。

在这里插入图片描述

在这里插入图片描述

360智脑,代码正常运行:

最长公共子序列(LCS)是一个在计算机科学中常见的问题,它需要找到两个序列中的最长公共子序列。下面是一个用Go语言实现的LCS函数:

package main

func lcs(X []int, Y []int) int {
	m := len(X)
	n := len(Y)

	if m == 0 || n == 0 {
		return 0
	}

	L := make([][]int, m+1)
	for i := range L {
		L[i] = make([]int, n+1)
	}

	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if X[i-1] == Y[j-1] {
				L[i][j] = 1+L[i-1][j-1]
			} else {
				L[i][j] = max(L[i-1][j], L[i][j-1])
			}
		}
	}

	return L[m][n]
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	X := []int{1, 0, 0, 1, 0, 1, 0, 1}
	Y := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}
	fmt.Println(lcs(X, Y))
}

在这个代码中,我们首先创建了一个二维数组L,其中L[i][j]表示X的前i个元素和Y的前j个元素的最长公共子序列的长度。然后,我们遍历X和Y,根据X[i-1]和Y[j-1]是否相等来更新L[i][j]。最后,L[m][n]就是X和Y的最长公共子序列的长度。

运行这段代码,我们可以得到X和Y的最长公共子序列的长度为4。

在这里插入图片描述

在这里插入图片描述

智谱清言,代码不完整:

为了找到两个序列的最长公共子序列 (LCS),我们可以使用动态规划的方法。在Go语言中实现这一算法,我们可以创建一个二维数组来存储子问题的解,并逐步构建LCS。

下面是一个使用Go语言实现的查找两个序列LCS的示例代码:

package main
import (
	"fmt"
)
// 计算最长公共子序列的长度
func LCSLength(X []string, Y []string) int {
	// 创建一个二维数组,用于存储子问题的解
	m := len(X)
	n := len(Y)
	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}
	// 初始化二维数组
	for i := 0; i <= m; i++ {
		for j := 0; j <= n; j++ {
			if i == 0 || j == 0 {
				dp[i][j] = 0
			}
		}
	}
	// 使用动态规划来填充二维数组
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if X[i-1] == Y[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1])
			}
		}
	}
	// dp[m][n] 包含了X[0..n-1] 和 Y[0..m-1]的LCS的长度
	return dp[m][n]
}
// 辅助函数,用于返回两个整数中的最大值
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
// 打印最长公共子序列
func printLCS(X []string, Y []string, dp [][]int) {
	m := len(X)
	n := len(Y)
	// 创建一个二维数组来存储LCS的子序列
	lcs := make([][]string, m+1)
	for i := range lcs {
		lcs[i] = make([]string, n+1)
	}
	// 从二维数组的右下角开始填充,以找出LCS
	for i := m; i >= 1; i-- {
		for j := n; j >= 1; j-- {
			if X[i-1] == Y[j-1] {
				lcs[i][j] = X[i-1]
				// 移动到左上角,即选择“相等”的选项
				i--
				j--
			} else if dp[i-1][j] > dp[i][j-1] {
				// 移动到左边的方格,即选择“从X中删除”的选项
				i--
			} else {
				// 移动到上方的方格,即选择“从Y中删除”的选项
				j--
			}
		}
	}
	// lcs[m][n] 包含了X[0..n-1] 和 Y[0..m-1]的LCS
	fmt.Println("最长公共子序列是: ")
	for _, value := range lcs[m] {
		if value != "" {
			fmt.Print(value, " ")
		}
	}
	fmt.Println()
}
func main() {
	X := []string{"1", "0", "0", "1", "0", "1", "0", "1"}
	Y := []string{"0", "1", "0", "1", "1", "0", "1", "1", "0"}
	// 计算LCS的长度
	length := LCSLength(X,

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

通义千问,代码正常运行:

LCS(Longest Common Subsequence)是指两个序列的最长公共子序列,它不一定是连续的子序列,但是要求相对顺序不变。

以下是使用Go语言实现的一个简单的动态规划解决方案:

package main

func lcs(a, b []int) []int {
    m, n := len(a), len(b)
    dp := make([][]int, m+1)
    for i := range dp {
        dp[i] = make([]int, n+1)
    }

    // 动态规划填充dp数组
    for i := 1; i <= m; i++ {
        for j := 1; j <= n; j++ {
            if a[i-1] == b[j-1] {
                dp[i][j] = dp[i-1][j-1] + 1
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
            }
        }
    }

    // 回溯得到LCS
    i, j := m, n
    res := []int{}
    for i > 0 && j > 0 {
        if a[i-1] == b[j-1] {
            res = append([]int{a[i-1]}, res...)
            i--
            j--
        } else if dp[i-1][j] > dp[i][j-1] {
            i--
        } else {
            j--
        }
    }

    return res
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func main() {
    a := []int{1, 0, 0, 1, 0, 1, 0, 1}
    b := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}
    fmt.Println(lcs(a, b))
}

这段代码首先通过动态规划计算出两个序列的最长公共子序列的长度,并存储在二维数组dp中。然后通过回溯的方式找到这个最长公共子序列。最后在main函数中调用lcs函数并打印结果。

注意:上述代码返回的是一个整数切片,即LCS的具体内容,由于输入的两个序列中相同的元素并不连续,所以LCS也是不连续的,这里直接返回了LCS的所有元素。

在这里插入图片描述

在这里插入图片描述

天工,panic:

在Go语言中,我们可以通过动态规划的方法来找到两个给定序列的 longest common subsequence (LCS)。下面是一个实现这一算法的Go语言函数:

package main

import "fmt"

// LCS computes the length of the longest common subsequence between X and Y.
func LCS(X, Y []int) int {
    m, n := len(X), len(Y)
    var dp [][]int
    dp = make([][]int, m+1)
    for i := range dp {
        dp[i] = make([]int, n+1)
    }
    
    // Initialize dp table
    for i := 0; i <= m; i++ {
        for j := 0; j <= n; j++ {
            if i == 0 || j == 0 {
                dp[i][j] = 0
            }
        }
    }
    
    // Fill the dp table
    for i := 1; i <= m; i++ {
        for j := 1; j <= n; j++ {
            if X[i-1] == Y[j-1] {
                dp[i][j] = dp[i-1][j-1] + 1
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
            }
        }
    }
    return dp[m][n]
}

// max returns the larger of two integers.
func max(a, b int) int {
    if a >= b {
        return a
    }
    return b
}

// LCSArray finds an actual LCS between X and Y.
func LCSArray(X, Y []int) []bool {
    m, n := len(X), len(Y)
    dp := make([][]int, m+1)
    for i := range dp {
        dp[i] = make([]int, n+1)
    }
    lcs := make([]bool, m+n+1)
    
    for i := 1; i <= m; i++ {
        for j := 1; j <= n; j++ {
            if X[i-1] == Y[j-1] {
                dp[i][j] = dp[i-1][j-1] + 1
                lcs[dp[i][j]] = true
            } else {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1])
            }
        }
    }
    
    var lcsStr string
    var lcsIndex int
    for i := 1; i <= min(len(X), len(Y)); i++ {
        if lcs[i] {
            lcsStr += "1"
            lcsIndex = i
        } else {
            lcsStr += "0"
        }
    }
    
    lcsArray := make([]bool, lcsIndex)
    for i, v := range lcsStr {
        lcsArray[i] = v == '1'
    }
    return lcsArray
}

// min returns the smaller of two integers.
func min(a, b int) int {
    if a <= b {
        return a
    }
    return b
}

func main() {
    X := []int{1, 0, 0, 1, 0, 1, 0, 1}
    Y := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}
    
    length := LCS(X, Y)
    fmt.Printf("The length of the LCS is: %d\n", length)
    
    lcs := LCSArray(X, Y)
    fmt.Println("An LCS:", lcs)
}

这段代码首先定义了一个计算LCS长度的函数LCS和返回实际LCS的函数LCSArray。然后,它使用这两个函数来处理输入序列并打印出LCS的长度以及一个实际的LCS。在main函数中,我们调用了LCSLCSArray函数来处理给定的序列。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

灵小智,代码正常运行:

下面是使用Go语言编写的代码,用于找到给定两个数组的最长公共子序列(LCS):

package main

import (
	"fmt"
)

func findLCS(arr1, arr2 []int) []int {
	m := len(arr1)
	n := len(arr2)

	// 创建二维数组用于存储LCS的长度
	dp := make([][]int, m+1)
	for i := 0; i <= m; i++ {
		dp[i] = make([]int, n+1)
	}

	// 填充dp数组
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if arr1[i-1] == arr2[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1])
			}
		}
	}

	// 根据dp数组回溯找到LCS
	lcs := make([]int, dp[m][n])
	index := dp[m][n] - 1
	i := m
	j := n
	for i > 0 && j > 0 {
		if arr1[i-1] == arr2[j-1] {
			lcs[index] = arr1[i-1]
			i--
			j--
			index--
		} else if dp[i-1][j] > dp[i][j-1] {
			i--
		} else {
			j--
		}
	}

	return lcs
}

// 辅助函数:返回两个整数的最大值
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	arr1 := []int{1, 0, 0, 1, 0, 1, 0, 1}
	arr2 := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}

	lcs := findLCS(arr1, arr2)
	fmt.Println("最长公共子序列:", lcs)
}

运行代码将输出:

最长公共子序列: [1 0 0 1 0 1]

这是给定两个数组 [1, 0, 0, 1, 0, 1, 0, 1][0, 1, 0, 1, 1, 0, 1, 1, 0] 的最长公共子序列。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

chatgpt,代码正常运行:

以下是使用Go语言编写的代码,求解给定序列的最长公共子序列(LCS):

package main

import "fmt"

func lcs(seq1, seq2 []int) []int {
	m := len(seq1)
	n := len(seq2)

	// 创建二维数组存储动态规划中间结果
	dp := make([][]int, m+1)
	for i := 0; i <= m; i++ {
		dp[i] = make([]int, n+1)
	}

	// 填充动态规划表
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if seq1[i-1] == seq2[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1])
			}
		}
	}

	// 回溯找出最长公共子序列
	lcsSeq := make([]int, 0)
	i, j := m, n
	for i > 0 && j > 0 {
		if seq1[i-1] == seq2[j-1] {
			lcsSeq = append(lcsSeq, seq1[i-1])
			i--
			j--
		} else if dp[i][j-1] >= dp[i-1][j] {
			j--
		} else {
			i--
		}
	}

	return reverse(lcsSeq)
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func reverse(seq []int) []int {
	n := len(seq)
	for i := 0; i < n/2; i++ {
		seq[i], seq[n-i-1] = seq[n-i-1], seq[i]
	}
	return seq
}

func main() {
	seq1 := []int{1, 0, 0, 1, 0, 1, 0, 1}
	seq2 := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}

	lcsSeq := lcs(seq1, seq2)

	fmt.Println("Longest Common Subsequence (LCS):", lcsSeq)
}

上述代码使用动态规划算法求解给定序列的最长公共子序列,输出结果为 [0,0,1,0,1]

在这里插入图片描述

在这里插入图片描述

kimi,代码不能运行:

最长公共子序列(Longest Common Subsequence,LCS)问题可以通过动态规划来解决。以下是一个使用 Go 语言实现的 LCS 算法,用于找到两个给定序列的最长公共子序列:

package main

import (
	"fmt"
)

// LCS 函数计算两个序列的最长公共子序列的长度
func LCS(x, y []int) (int, []int) {
	m, n := len(x), len(y)
	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}

	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if x[i-1] == y[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1])
			}
		}
	}

	// 回溯找到最长公共子序列
	result := make([]int, dp[m][n])
	i, j := m, n
	for i > 0 && j > 0 {
		if x[i-1] == y[j-1] {
			result[--i] = x[i-1]
			j--
		} else if dp[i-1][j] > dp[i][j-1] {
			i--
		} else {
			j--
		}
	}

	return dp[m][n], result
}

// max 返回两个整数中的最大值
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	x := []int{1, 0, 0, 1, 0, 1, 0, 1}
	y := []int{0, 1, 0, 1, 1, 0, 1, 1, 0}

	length, lcs := LCS(x, y)
	fmt.Printf("Length of LCS: %d\n", length)
	fmt.Printf("LCS:        %v\n", lcs)
}

在这个程序中,LCS 函数接受两个整数切片 xy 作为输入,并返回这两个序列的最长公共子序列的长度以及子序列本身。我们使用一个二维数组 dp 来存储子问题的解,其中 dp[i][j] 表示序列 x 的前 i 个元素和序列 y 的前 j 个元素的最长公共子序列的长度。然后,我们通过回溯 dp 数组来构建最长公共子序列。

运行这个程序,你将得到序列 <1, 0, 0, 1, 0, 1, 0, 1><0, 1, 0, 1, 1, 0, 1, 1, 0> 的最长公共子序列及其长度。

在这里插入图片描述

在这里插入图片描述

混元,代码正常运行:

这两个序列的最长公共子序列(LCS)是:〈0,1,0,1,0,1,0,1〉。

以下是使用 Go 语言实现的求解两个序列的 LCS 的代码:

package main

import (
	"fmt"
)

func longestCommonSubsequence(text1 string, text2 string) string {
	m, n := len(text1), len(text2)
	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}

	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if text1[i-1] == text2[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else {
				dp[i][j] = max(dp[i-1][j], dp[i][j-1])
			}
		}
	}

	lcs := ""
	i, j := m, n
	for i > 0 && j > 0 {
		if text1[i-1] == text2[j-1] {
			lcs = string(text1[i-1]) + lcs
			i--
			j--
		} else if dp[i-1][j] > dp[i][j-1] {
			i--
		} else {
			j--
		}
	}

	return lcs
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func main() {
	text1 := "10010101"
	text2 := "010110110"
	fmt.Println(longestCommonSubsequence(text1, text2))
}

这段代码首先定义了一个 longestCommonSubsequence 函数,输入为两个字符串,输出为它们的 LCS。函数内部使用动态规划算法求解 LCS 的长度,并根据 dp 数组还原出 LCS。最后在 main 函数中调用该函数并输出结果。

在这里插入图片描述

在这里插入图片描述

总结

代码能正常运行的,答案没问题。普天同庆。

posted @ 2024-03-01 09:57  福大大架构师每日一题  阅读(25)  评论(0编辑  收藏  举报