最常见的子列表

时间:2010-11-07 21:03:15

标签: functional-programming scheme racket

在尝试为Scheme中最长的常见子列表问题编写解决方案时,我无法弄清楚到目前为止我所遇到的问题。我认为这是正确的想法,在担心多项式时间之前,我只想尝试一个可以工作的时间。我以前没有用函数式语言编写,语法差异一开始可能会让事情变得更难。

(define (lcs lst1 lst2)
(if (or (null? lst1) (null? lst2)) '()
      (if (not (null? lcs)) lcs
          (if (equal? (car lst1) (car lst2))
              (cons (car lst1))(lcs (cdr lst1) (cdr lst2)))
          (let ((a (lcs (cdr lst1) lst2))
                (b (lcs lst1 (cdr lst2))))
            (if (> (cadr a) (cadr b)) a b)))))

这是在正确的轨道上吗?它出什么问题了? 感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:3)

(if (not (null? lcs)) lcs

在这里,您要检查lcs(这是一个函数)是否为空列表。如果不是(由于函数不是列表,情况总是如此),则返回函数本身。

我假设你打算做的是调用函数lcs并检查结果是否为空列表。要调用函数,您需要在括号中包围该函数。此外,如果函数接受参数(lcs执行),则需要在调用函数时指定这些参数。

我不清楚这个if应该完成什么,据我所知,没有必要,所以只需删除它。

(if (> (cadr a) (cadr b)) a b)

cadr返回列表的第二个元素,所以在这里你返回第二个元素更大的列表。鉴于您的目标是找到最长的子列表,这没有任何意义。您应该返回长度更长的列表。为此,请使用

替换条件
(> (length a) (length b))

除了那些逻辑错误之外,还有一个小的语法错误:

(cons (car lst1)) (lcs (cdr lst1) (cdr lst2)))

这里你用一个参数调用cons(这是一个错误),然后调用(lcs (cdr lst1) (cdr lst2))作为列表的else部分。由于您显然希望(lcs (cdr lst1) (cdr lst2))成为cons的第二个参数,因此请在car lst1之后删除第二个结束参数。