首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >lisp函数(普通lisp中的计数)

lisp函数(普通lisp中的计数)
EN

Stack Overflow用户
提问于 2015-08-20 09:57:30
回答 2查看 920关注 0票数 1

我正在编写与C和lisp中的偶数处理不同的程序,完成了我的c程序,但对lisp仍然有困难。

定义了isprime函数,我需要在以下方面提供帮助:

  1. 定义在lis中返回唯一素数的函数primesinlist

到目前为止,我得到了什么,有什么帮助吗?

代码语言:javascript
复制
(defun comprimento (lista)
  (if (null lista)
      0
    (1+ (comprimento (rest lista)))))

代码语言:javascript
复制
 (defun primesinlist (number-list)
      (let ((result ()))
        (dolist (number number-list)
          (when (isprime number)
            ( number result)))
        (nreverse result))) 

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-20 11:03:16

在处理之前,需要先对参数进行flatten

代码语言:javascript
复制
(defun primesinlist (number-list)
  (let ((result ()))
    (dolist (number (flatten number-list))
      (when (isprime number)
        (push number result)))
    (delete-duplicates (nreverse result))))

或者,如果您想避免混淆一个鲜食列表,可以在执行过程中将其扁平化:

代码语言:javascript
复制
(defun primesinlist (number-list)
  (let ((result ()))
    (labels ((f (l)
               (dolist (x l)
                 (etypecase x
                   (integer (when (isprime x)
                              (push x result)))
                   (list (f x))))))
      (f number-list))
    (delete-duplicates (nreverse result))))

要计数不同的素数,请取primesinlist返回的列表的primesinlist

或者,您可以使用count-if

代码语言:javascript
复制
(count-if #'isprime (delete-duplicates (flatten number-list)))
票数 2
EN

Stack Overflow用户

发布于 2015-08-20 13:39:16

听起来您已经实现了一个原始性测试,但是为了完整起见,让我们添加一个非常简单的测试,它只是尝试将一个数字除以小于它的平方根的数字:

代码语言:javascript
复制
(defun primep (x)
  "Very simple implementation of a primality test.  Checks 
for each n above 1 and below (sqrt x) whether n divides x.
Example:
  (mapcar 'primep '(2 3 4 5 6 7 8 9 10 11 12 13))
  ;=> (T T NIL T NIL T NIL NIL NIL T NIL T)
"
  (do ((sqrt-x (sqrt x))
       (i 2 (1+ i)))
      ((> i sqrt-x) t)
    (when (zerop (mod x i))
      (return nil))))

现在,您需要一种方法将可能嵌套的列表压缩为单个列表。在处理这个问题的时候,我通常会发现,用构造的单元格构建的树更容易思考。这里有一个高效的扁平化函数,它返回一个全新的列表。也就是说,它不与原始树共享任何结构。这可能很有用,特别是如果我们希望稍后修改结果结构,而不修改原始输入。

代码语言:javascript
复制
(defun flatten-tree (x &optional (tail '()))
  "Efficiently flatten a tree of cons cells into 
a list of all the non-NIL leafs of the tree.  A completely
fresh list is returned.

Examples:
  (flatten-tree nil)                ;=> ()
  (flatten-tree 1)                  ;=> (1)
  (flatten-tree '(1 (2 (3)) (4) 5)) ;=> (1 2 3 4 5)
  (flatten-tree '(1 () () 5))       ;=> (1 5)
"
  (cond
    ((null x) tail)
    ((atom x) (list* x tail))
    ((consp x) (flatten-tree (car x)
                             (flatten-tree (cdr x) tail)))))

现在,这只是一个扁平化列表的问题,删除不是素数的数字,并从该列表中删除重复项。公共Lisp包括用于执行这些操作的函数,即remove-duplicates. --如果不是和。这些是不修改输入参数的“安全”版本。因为我们知道扁平化列表是新生成的,所以我们可以使用它们的(潜在的)破坏性对应,删除如果不是和。

但是,在删除重复元素时有一个警告。如果您有一个类似于(13 5 3)的列表,可以返回两个可能的结果(假设您保持所有其他元素的顺序):(15 5)(15 3)。也就是说,您可以删除后一个副本或早期副本。一般来说,你有一个问题:“哪一个应该落在后面?”默认情况下,公共Lisp删除前面的副本,并留下最后一个重复。该行为可以由:from-end关键字参数自定义。在您自己的API中复制这种行为是很好的。

因此,这里有一个函数,它将所有这些考虑因素结合在一起。

代码语言:javascript
复制
(defun primes-in-tree (tree &key from-end)
  "Flatten the tree, remove elements which are not prime numbers,
using FROM-END to determine whether earlier or later occurrences
are kept in the list.

Examples:
  (primes-in-list '(2 (7 4) ((3 3) 5) 6 7))
  ;;=> (2 3 5 7)

  (primes-in-list '(2 (7 4) ((3 3) 5) 6 7) :from-end t)
  ;;=> (2 7 3 5)"

  ;; Because FLATTEN-TREE returns a fresh list, it's OK
  ;; to use the destructive functions DELETE-IF-NOT and
  ;; DELETE-DUPLICATES.
  (delete-duplicates
   (delete-if-not 'primep (flatten-tree list))
   :from-end from-end))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32115136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档