所以我有一个整数列表,我正在尝试找到索引
list(i) > list(i+1)
我有基本情况,如果列表为空或长度为1,它将返回列表长度,但我在实际遍历列表并跟踪索引时遇到问题。
我现在的代码:
(defunc out-of-order (l)
(cond ((or (equal (length l) 0) (equal (length l) 1)) (length l))
; this is where the index search goes
)
答案 0 :(得分:2)
编写一个递归函数,该函数接受“已经遍历的节点数”的参数。在out-of-order
内,使用0
作为已经遍历的数字调用该函数。
......这足以暗示你了吗?再试一次,看看你能不能得到它。
另一个提示
(defun out-of-order (lst)
(out-of-order-rec lst 0))
(defun out-of-order-rec (lst i)
(if (or (endp lst) (endp (cdr lst)))
; something...
(if (> (car lst) (car (cdr lst)))
; something...
; something...
)))
答案 1 :(得分:2)
这是一种概述问题解决方法的模板。
(defun out-of-order (list)
(labels ((recur (list index)
(cond ((or #<list is empty> #<list only has one item>)
nil)
((> #<the first item> #<the second item>)
index)
(t
(recur #<advance the recursion> #<increment the index>)))))
(recur list 0)))
自己思考流程的各个部分(#<these things>
),以及它们各自如何为解决方案做出贡献。填写它们将引导您找到解决方案,我认为还可以帮助您更好地理解递归过程。
当然,如果有任何不清楚的部分,请发表评论。
如果您不熟悉labels,这里的逻辑相同,但使用外部帮助程序:
(defun out-of-order-aux (list index)
(cond ((or #<list is empty> #<list only has one item>)
nil)
((> #<the first item> #<the second item>)
index)
(t
(out-of-order-aux #<advance the recursion> #<increment the index>))))
(defun out-of-order (list)
(out-of-order-aux list 0))
答案 2 :(得分:0)
无需递归执行此操作。在Common Lisp中,将它表达为显式循环更为惯用。这导致更多可移植代码,因为不需要Common Lisp实现来消除尾调用。
您可以使用简单的loop
解决此问题。您有三个循环变量:当前元素,下一个元素和当前索引。只要找到满足条件的当前和下一个元素,就会返回当前索引。
(defun find-downstep-index (list)
(if (endp (rest list))
(length list)
(loop :for current-element :in list
:for next-element :in (rest list)
:for current-index :upfrom 0
:when (> current-element next-element)
:do (return-from find-downstep-index current-index)
:finally (return (+ current-index 2)))))
(如果没有找到这样的索引,则返回列表长度的特殊行为会导致相当 ad hoc 初始保护并且最后添加2。更常见的是返回在这种情况下nil
,但也许在周围使用中会有一些优化。)