如何改进该算法 (LCS)

发布于 2024-08-27 22:12:54 字数 716 浏览 5 评论 0原文

  (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))))))**

我不想让它一遍又一遍地运行..

问候, 超级守护者

  (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))))))**

I dont want it to run over and over..

Regards,
Superguay

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

能怎样 2024-09-03 22:12:54

我发现这应该采用两个列表的最长公共子序列。正如您所指出的,它非常慢。如果你想让它更快地工作,你需要采取一种更复杂的方法,而不仅仅是像这样暴力破解;规范的解决方案是这篇维基百科文章中描述的动态规划算法。

无需完全切换到不同算法即可大大加快解决方案速度的一种方法是通过记忆结果,因为就目前情况而言,当您递归并从列表末尾删除元素时,您将一遍又一遍地计算相同的中间结果。

编辑:嗯,一种简单的方法,使其更快一点,而不需要太多工作,就是使用 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))))

希望它是正确的 - 我没有解释器方便 - 但你明白了。

I see that this is supposed to take the longest common subsequence of two lists. As you noted, it's pretty slow. You will need to take a more complicated approach than just brute-forcing it like this if you want it to work more quickly; the canonical solution is the dynamic programming algorithm described in this Wikipedia article.

One way you could vastly speed up your solution without totally switching to a different algorithm is through memoization of the results, since as it stands you'll be computing the same intermediate results over and over as you recurse and drop elements from the ends of the lists.

EDIT: Well, an easy way to make it a bit faster without much work would be to use a let clause to avoid extra work at the bottom, i.e.

(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))))

Hope it's correct - I don't have an interpreter handy - but you get the picture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文