我正在为即将到来的考试解决一些问题,我需要一些关于这个Lisp函数的帮助。我在CLISP工作。 我必须找到列表中仅包含奇数的最长递减序列。 例如:
(longest '(13 9 3 7 4 7 5 3 2 8 15 11 9 7 3))
应该返回:
(15 11 9 7 3)
唯一的强制要求是必须以递归方式实现该函数:)
答案 0 :(得分:1)
使用连续的子序列,很容易。除了我没有lisp,所以我必须用文字解释。
current
,重复尾巴。当到达列表的末尾时,两个记住的列表中的较长时间就是答案。
答案 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。