gpt4 book ai didi

LISP FUNCTION - 返回列表中大于第一个元素的数字的计数

转载 作者:太空宇宙 更新时间:2023-11-03 18:55:55 28 4
gpt4 key购买 nike

我想解决一个 lisp 函数,该函数返回大于列表中第一个数字的 NUMBER(count) 个数字。该列表是数字的线性列表。

(defun foo (lst) 
(cond ((null lst) 0)
(car = k)
((> (car lst) k)
(1+ (foo (cdr lst))))
(T (foo (cdr lst)))))

我的问题是我无法保留第一个元素并将其与其他元素进行比较。

最佳答案

让我们分解一下您的问题:

你有一组数字。真的,你有一个“特殊”的第一个数字,然后是其余的数字。具体来说,您可能只需要实数,因为“小于”对于复数(虚数)没有意义。

您可以使用 first 从列表中获取第一个数字,并使用 rest 获取其他数字。

其中,您想计算不大于第一个的任何一个。

所以让我们从一些伪代码开始

(defun count-numbers-greater-than-first (list)
;; split out first and rest
;; call the real count function
)

好吧,我们现在知道我们可以使用 firstrest(也像您以前使用的那样,carcdr ),所以:

(defun count-numbers-greater-than-first (list)
(count-numbers-greater-than (first list) (rest list))

您可能已经知道 > 用于测试实数是否大于另一个数。

快速浏览 CLHS 会发现一个名为 count-if 的好函数

(defun count-numbers-not-greater-than (reference other-numbers)
(count-if ??? other-numbers))

???需要是function类型的对象,或者是函数名。我们需要将 reference(第一个数字)“curry”到该函数中。这意味着我们要创建一个新函数,它只用于通过 count-if 的一次运行,它已经“关闭”了 reference 的值。

如果我们知道 number 永远是,比方说,100,那么该函数将如下所示:

(defun greater-than-100 (number)
(> number 100))

然后可以在 count-if 中使用该函数:

(defun count-numbers-greater-than (reference other-numbers)
(count-if (function greater-than-100)
other-numbers))

(defun count-numbers-greater-than (reference other-numbers)
(count-if #'greater-than-100 other-numbers))

但这并没有解决将 reference 数字“curried”到函数中的问题。

无需访问 Alexandria(我稍后会解释),您可以在此处使用 lambda 形式创建一个新的匿名函数。由于 referencecount-numbers-not-greater-than 中可用,您可以在 lambda 中使用它的值。让我们先转换为 100:

(defun count-numbers-greater-than (reference other-numbers)
(count-if (lambda (number) (> number 100))
other-numbers))

现在我们可以使用reference:

(defun count-numbers-greater-than (reference other-numbers)
(count-if (lambda (number) (> number reference))
other-numbers))

事实上,如果您愿意,您甚至可以将它合并回另一个函数:

(defun count-numbers-greater-than-first (list)
(count-if (lambda (number) (> number (first list)))
(rest list)))

亚历山大的事

但是,亚历山大呢? Alexandria 是 Quicklisp 或其他地方提供的 super 有用的实用函数的集合。

 (ql:quickload "alexandria")

(use-package #:alexandria)

当然,您通常会在自己的 defpackage使用

 (defpackage my-cool-program
(:use :common-lisp :alexandria))

它提供的两个东西是 curryrcurry 函数。事实证明,其中的 lambda 函数非常常见。你有一个现有的函数——在这里,>——你想用相同的值一遍又一遍地调用它,还有一些你想每次都传入的未知值。

这些最终看起来很像这样:

 (lambda (x) (foo known x))

你可以使用curry来更简洁地写同样的东西:

 (curry #'foo known)

它也适用于任意数量的参数。 RCurry 做同样的事情,但它将未知值“x”放在左边,而你的已知值放在右边。

 (lambda (x) (foo x known)) = (rcurry #'foo known)

所以另一种编写count-if的方法是:

(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

关于LISP FUNCTION - 返回列表中大于第一个元素的数字的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41723509/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com