我正在尝试编写一个函数来计算两个输入字符串str1
和str2
的最长公共子序列的长度。
这就是我现在所拥有的,
(define LCS
(lambda (str1 str2)
(if (OR (equal? str1 "") (equal? str2 ""))
0
(if (equal? (string-contains str1 (string-ref str2 0)) #t)
(+ 1 (LCS (substring str1 1 (string-length str1))
(substring str2 1 (string-length str2))))
(LCS (substring str1 1 (string-length str1))
(substring str2 1 (string-length str2)))))))
如果字符串中包含某个字符,则string-contains
返回 true 。现在它似乎有效,但我认为可能存在错误。
答案 0 :(得分:2)
如果您不介意相对较慢的算法,您的代码完全在正确的轨道上;如果你需要更快的话,可以使用动态编程来解决这个问题。
现在,您的代码中的错误是您在每次递归调用的同时向下移动两个字符串的长度。它会失败,例如(我认为,我没有尝试过)使用以下两个字符串:(LCS "scheme" "emesch")
原因是匹配的子字符串不是从第一个和第二个字符串中的相同位置开始。
我建议你将递归分成两个递归调用:一个是从第一个字符串前面删除一个字符,另一个是从第二个字符串前面删除一个字符。然后,您从这些呼叫中获取最佳结果。以这种方式,你可以确定你会找到子串,无论它们在另一个字符串中的位置。
答案 1 :(得分:0)
并行扫描两个字符串。如果当前两个字符相同,则最长公共子序列的长度增加1,并且扫描在每个字符串中的下一个字符处继续;否则,在从一个输入序列或另一个输入序列中删除当前字符后,有两种可能需要递归考虑,并且最长公共子序列的长度只是两种可能性中较大的一种。
我的blog可以获得更完整的解释和方案实施。