我尝试使用Scheme实现LCS算法,但是有一个错误。
(定义X (列表#\ A#\ B#\ C#\ B#\ D#\ A#\ B))
(定义Y (列表#\ B#\ D#\ C#\ A#\ B#\ A))
(定义前缀 (lambda(i s) (如果(= i 0) '() (缺点(汽车) (前缀(-i 1) (cdr s)))))))
(定义(选择) (如果(= ith 1) (汽车) (选择(第1个) (cdr s))))
(定义(LCS x y) (定义(最佳i j) (cond((或(= i 0) (= j 0)) 0) ((eq?(pick i x) (选择j y)) (+1 (最佳(-i 1) (-j 1)))) (否则(最大值(LCS(前缀(-i 1)x)y) (LCS x(前缀(-j 1)y)))))) (最佳(长度x) (长度y)))
1] =>(加载“ lcs.scm”)
;正在加载“ lcs.scm” ...完成 ;值:lcs
1] =>(lcs X Y)
;值:5
结果应该是4,我不知道错误在哪里。
答案 0 :(得分:0)
您收到错误消息,因为最终的最佳递归调用不正确。
您将i-1
的前缀x
或j-1
的前缀y
当作其他前缀。 j
和i
可能小于相应字符串的长度,因此,您需要相应地在参数前加上前缀。
以下代码正常工作。
(define (LCS x y)
(define (optimal i j)
(cond
((or (= i 0) (= j 0)) 0)
((eq? (pick i x) (pick j y)) (+ 1 (optimal (- i 1) (- j 1))))
(else (max (LCS (prefix (- i 1) x) (prefix j y)) (LCS (prefix i x) (prefix (- j 1) y))))))
(optimal (length x) (length y)))
请注意,此问题仅存在是因为您混用了两种不同类型的呼叫。一个在前缀上调用LCS
,另一个在i和j较小的情况下调用optimal
。
您可以将最佳的LCS
调用替换为更简单的解决方案。
(define (LCS x y)
(define (optimal i j)
(cond
((or (= i 0) (= j 0)) 0)
((eq? (pick i x) (pick j y)) (+ 1 (optimal (- i 1) (- j 1))))
(else (max (optimal (- i 1) j) (optimal i (- j 1))))))
(optimal (length x) (length y)))