Lisp中最长的递减序列

时间:2011-12-21 22:18:30

标签: algorithm list lisp sequence

我正在为即将到来的考试解决一些问题,我需要一些关于这个Lisp函数的帮助。我在CLISP工作。 我必须找到列表中仅包含奇数的最长递减序列。 例如:

(longest '(13 9 3 7 4 7 5 3 2 8 15 11 9 7 3))

应该返回:

(15 11 9 7 3)

唯一的强制要求是必须以递归方式实现该函数:)

3 个答案:

答案 0 :(得分:1)

使用连续的子序列,很容易。除了我没有lisp,所以我必须用文字解释。

  1. 调用递归助手,使用附加参数a)到目前为止发现最长的b)c)当前子序列的长度d)其长度。最初这些是()0()0。
  2. 虽然列表的头部是偶数,但尾巴重复。
  3. 以遇到的第一个奇怪的方式开始current,重复尾巴。
  4. 如果磁头是偶数,或磁头不小于前一个元素,则当前序列停止。将其长度与先前找到的最长序列进行比较。如果电流更长,则成为新的最长,否则忘记电流。转到2.
  5. 当到达列表的末尾时,两个记住的列表中的较长时间就是答案。

答案 1 :(得分:1)

你可以在一个阶段使用递归(这比我将建议的方法更快,更高效)来做到这一点,但如果你生成所有的,它可能更具可读性,模块化和更简单的代码首先是可能的解决方案,按有效的解决方案进行过滤,然后返回最好的解决方案。

要做到这一点,你需要一台发电机&映射函数(我建议这个问题有两个嵌套的maplist),一个过滤函数(写一个;减少奇数;然后查看lisp的'remove-if-not函数),和一个reduce函数(返回最佳解决方案(最长)列表)来自过滤的)。

SICP中有一节讨论了这种方法:http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2

  

信号处理工程师会发现概念化很自然   这些过程就流过级联的信号而言   阶段...

答案 2 :(得分:0)

Daniel's answer中的算法转换为Haskell,并进行了一些调整:

longest_sub xs = g2 xs [] 0 
  where
    g2 [] a _ = a
    g2 (x:t) a i  
         | even x    = g2 t a i 
         | otherwise = g4 t [x] 1
      where
        g4 [] b j = if j>i then reverse b else reverse a
        g4 xs@(x:t) b j            
             | even x || x >= head b
                         = if j>i then g2 xs b j 
                                  else g2 xs a i 
             | otherwise = g4 t (x:b) (j+1)

在Common Lisp中:

(defun longest (xs)
  (prog  ((a nil) (i 0) b j x)                  ; var decls
      G2  (if (null xs) (return (reverse a)))   ; code
          (setf x (car xs) xs (cdr xs))
          (if (evenp x)
              (go G2))
      G3  (setf b (list x) j 1)
      G4  (if (null xs)
              (if (> j i)
                  (return (reverse b))
                  (return (reverse a))))
          (setf x (car xs) xs (cdr xs))
          (when (evenp x)
              (if (> j i) (setf a b i j))
              (go G2))
          (when (>= x (car b))
              (if (> j i) (setf a b i j))
              (go G3))
          (setf b (cons x b) j (+ j 1))
          (go G4)))

函数调用毕竟是一个美化的GOTO,不是吗?

另见:prog doc page