如何改进此算法(LCS)

时间:2010-04-08 05:38:38

标签: scheme

  (define (lcs lst1 lst2)
   (define (except-last-pair list)
   (if (pair? (cdr list))
   (cons (car list) (except-last-pair (cdr list)))
   '()))
  (define (car-last-pair list)
   (if (pair? (cdr list))
   (car-last-pair (cdr list))
   (car list)))
  (if (or (null? lst1) (null? lst2)) null
   (if (= (car-last-pair lst1) (car-last-pair lst2))
      (append (lcs (except-last-pair lst1) (except-last-pair lst2)) (cons (car-last-pair lst1) '()))
      (**if (> (length (lcs lst1 (except-last-pair lst2))) (length (lcs lst2 (except-last-pair lst1)))) 
          (lcs lst1 (except-last-pair lst2))
          (lcs lst2 (except-last-pair lst1))))))**

我不希望它一遍又一遍地运行..

此致 Superguay

1 个答案:

答案 0 :(得分:1)

我看到这应该是两个列表中最长的共同子序列。如你所知,它很慢。如果你想让它更快地工作,你需要采取一种更复杂的方法,而不仅仅是强制它。规范解决方案是this Wikipedia article中描述的动态编程算法。

在不完全切换到不同算法的情况下,您可以大大加快解决方案的一种方法是通过结果的memoization,因为当你表现出来时,你将会一遍又一遍地计算相同的中间结果。从列表末尾删除元素。

编辑:嗯,如果没有太多工作,一个简单的方法就是使用let条款来避免额外的工作,即

(if (or (null? lst1) (null? lst2)) null
  (let ((front1 (except-last-pair lst1)) (front2 (except-last-pair lst2)))
    (if (= (car-last-pair lst1) (car-last-pair lst2))       
      (append (lcs front1 front2) (cons (car-last-pair lst1) '()))
      (let ((sub-lcs1 (lcs lst1 front2)) (sub-lcs2 (lcs lst2 front1)))
        (if (> (length sub-lcs1) (length sub-lcs2)) 
          sub-lcs1
          sub-lcs2))))

希望这是正确的 - 我没有一个方便的翻译 - 但你得到了照片。