LISP函数-返回列表中大于第一个元素的数字的计数
我想解一个lisp函数,它返回一个大于列表中第一个数字的数字计数。列表是一个线性数字列表LISP函数-返回列表中大于第一个元素的数字的计数,lisp,common-lisp,Lisp,Common Lisp,我想解一个lisp函数,它返回一个大于列表中第一个数字的数字计数。列表是一个线性数字列表 (defun foo (lst) (cond ((null lst) 0) (car = k) ((> (car lst) k) (1+ (foo (cdr lst)))) (T (foo (cdr lst))))) 我的问题是,我无法保留第一个元素并将其与其他元素进行比较。您的函数正确缩进如下所示: (defun greater-than
(defun foo (lst)
(cond ((null lst) 0)
(car = k)
((> (car lst) k)
(1+ (foo (cdr lst))))
(T (foo (cdr lst)))))
我的问题是,我无法保留第一个元素并将其与其他元素进行比较。您的函数正确缩进如下所示:
(defun greater-than-100 (number)
(> number 100))
(lambda (x) (foo known x))
德芬福斯特酒店
cond null lst 0
car=k;奇异第二项
>汽车lst k
1+foo cdr lst
T foo cdr lst
我已经评论了你的第二个任期。这很奇怪。它首先评估变量car,而不是函数car。如果car不是nil,它首先计算变量=而不是函数'=并且因为它不是第二项中的最后一个后续表达式,所以它会丢弃它并返回最后一个,即k
第二,你写你说你使用第一个元素作为比较,但是你在你的函数中称它为k,但是它没有在任何地方定义。在执行递归之前需要做一些事情,因此不能让实际函数执行递归,因为它每次都会使用第一个元素。以下是可以使用标签的位置:
;; 没有叫它foo,因为它不是很有描述性
defun计数大于第一个列表
让我们把第一辆车列出来
标签帮助器列表
cond null列表0
>汽车清单第一
1+助手cdr列表
t助手cdr列表
助手cdr列表
当然。既然您现在可以添加更多参数,我会添加一个累加器:
defun计数大于第一个列表
让我们把第一辆车列出来
标签帮助器列表acc
条件空列表acc
>汽车清单第一
助手cdr列表1+acc
t助手cdr列表acc
帮助程序cdr列表0
当然,递归可能会破坏堆栈,因此您应该在不使用Common Lisp的情况下编写它:
defun计数大于第一个列表
让我们把第一辆车列出来
循环:对于cdr列表中的元素
:计数>元素优先
还有更适合计算的高阶函数:
defun计数大于第一个列表
让我们把第一辆车列出来
如果lambda元素>元素优先,则计数
cdr列表
让我们来分析一下你的问题: 你有一组数字。真的,你有一个“特殊”的第一个号码,然后是其他号码。具体来说,您可能只需要实数,因为“小于”对于复数来说没有意义 您可以使用first从列表中获取第一个数字,其余的用于其他数字 其中,您要计算不大于第一个值的任何值 让我们从伪代码开始
(defun count-numbers-greater-than-first (list)
;; split out first and rest
;; call the real count function
)
好的,我们现在知道我们可以使用first和rest,正如您使用的,历史上的car和cdr,所以:
您可能已经知道>用于测试实数是否大于其他实数
快速查看CLHS可以发现一个很好的函数,名为count if
那个???必须是函数类型的对象,或函数的名称。我们需要将引用的第一个数字“curry”到该函数中。这意味着我们要创建一个新函数,该函数仅用于一次运行计数if,它已经“关闭”了引用值
如果我们知道这个数字总是,比如说,100,那么这个函数会是这样的:
(defun greater-than-100 (number)
(> number 100))
(lambda (x) (foo known x))
如果出现以下情况,则可在计数中使用该函数:
但这并不能解决将参考号“curried”放入函数中的问题
在不涉及Alexandria的情况下,我马上解释一下,您可以使用lambda表单在这里创建一个新的匿名函数。由于引用在不大于的计数中可用,因此可以在该lambda中使用其值。让我们先换算为100:
(defun count-numbers-greater-than (reference other-numbers)
(count-if (lambda (number) (> number 100))
other-numbers))
现在我们可以参考:
事实上,如果您愿意,您甚至可以将此函数合并回另一个函数:
(defun count-numbers-greater-than-first (list)
(count-if (lambda (number) (> number (first list)))
(rest list)))
亚历山大的那件事
但是,亚历山大怎么样?Alexandria是Quicklisp或其他地方提供的超级有用的实用程序函数的集合
(ql:quickload "alexandria")
(use-package #:alexandria)
当然,您通常会在自己的软件包中使用它
它提供的两个功能是curry和rcurry函数。事实证明,这里的lambda函数是一种非常常见的情况。您有一个现有的函数-这里是>-您想用相同的值反复调用,还有一些未知的值,您想每次传入
这些最终看起来非常像这样:
(defun greater-than-100 (number)
(> number 100))
(lambda (x) (foo known x))
你可以用咖喱更简洁地写同样的东西:
(curry #'foo known)
它还可以处理任意数量的参数。RCurry也这样做,但它将未知值“x”放在左侧,将已知值放在右侧
(lambda (x) (foo x known)) = (rcurry #'foo known)
因此,另一种写入计数的方法是:
到目前为止你尝试了什么?德芬
foo lst cond null lst 0 car=k>car lst k 1+foo cdr lst foo cdr lstim不太熟悉lisp,因为我是新手..我认为我很接近,但我的问题是我无法保留第一个元素并将其与others@TasosCe:您不能“保留第一个元素”是什么意思?你知道什么是变量吗?非常感谢你的帮助。我测试了它,它工作得很好!另外,感谢您在开始时提供的有用建议,我理解关于我在k和标签使用上的错误的一切:!!哇,非常感谢您的解释,每个解决方案都非常完美,完全可以理解!
(lambda (x) (foo x known)) = (rcurry #'foo known)
(defun count-numbers-greater-than-first (list)
(count-if (rcurry #'> (first list))
(rest list)))
* (count-numbers-greater-than-first '(10 9 8 7 11 12))
2