List 如何基于scheme中另一个函数的求值向列表递归添加元素

List 如何基于scheme中另一个函数的求值向列表递归添加元素,list,recursion,append,scheme,List,Recursion,Append,Scheme,我有以下代码,其中我尝试根据是否为素数将列表中的所有元素添加到新列表中: (define (findPrimes newLis lis) (cond ((null? lis) ()) (else ( (cond ((#t (isPrime (CAR lis)))

我有以下代码,其中我尝试根据是否为素数将列表中的所有元素添加到新列表中:

(define (findPrimes newLis lis)
    (cond
            ((null? lis) ())
            (else 
                (
                    (cond 
                        ((#t (isPrime (CAR lis)))
                            (append newLis (CAR lis))))
                    (findPrimes newLis (CDR lis))
              ))
          )

        newLis
    )

然而,我得到了一个错误。我对scheme非常陌生,因此如果此代码完全错误,我向您道歉。

是的,您有很多多余的括号。每一对括号都很重要,在这个方案中,我们不能仅仅通过它们来衡量
(fx)
表示“使用参数
x
调用函数
f
”,因此
((fx))
表示“使用参数
x
调用函数
f
,然后将该调用的结果视为函数,并(再次)在没有任何参数的情况下调用它”。这肯定会引起麻烦,可能性更大

你想写的是

(define (findPrimes newLis lis)
    (cond
            ((null? lis)   (set! newLis '()))
            (else 
                (cond 
                   ((equal? #t (isPrime (CAR lis)))
                           (set! newLis 
                                 (append newLis (list (CAR lis))))
                           (findPrimes newLis (CDR lis)))
                   (else
                           (findPrimes newLis (CDR lis)))))))
但这完全是错误的。对于初学者来说,
(findpromes'()(list 2 3 4 5 6 7 8 9 10))
不返回任何内容——不管参数是什么

您需要更改基本案例处理。在递归情况下,建立作为第一个参数传入的列表;然后,当我们到达输入列表的末尾(第二个参数)时,您如何处理现在准备好的新列表?您将其设置为
”()
!您不返回任何值(因为
set!
不返回任何值)

因此,这很容易解决:只需返回您构建的值。最后一个表达式的值是作为整个函数的值返回的值。然后您就得到了想要返回的值,即新列表。因此,您将它作为基本case
cond
子句中的最后一个表达式。所以现在它起作用了

但是,它工作得不好。它在时间上是二次的(因为重复的
append
)。这通常意味着执行时间非常缓慢。另外,使用
set
是一个指标,表明某些内容可能不太正确

通常的做法是

(define (findPrimes lis)
    (cond
            ((null? lis)               '() )
            (else 
                (cond 
                   (           (isPrime (CAR lis))
                           (cons                      (CAR lis)
                             (findPrimes        (CDR lis))))
                   (else
                             (findPrimes        (CDR lis)))))))
看看你输入的东西少了多少

这又是一个标准间距:

(define (findPrimes lis)
  (cond
    ((null? lis) '() )
    ((isPrime (car lis))
     (cons (car lis)
           (findPrimes (cdr lis))))
    (else
     (findPrimes (cdr lis)))))

还有一两件事我也改变了。您能告诉我是什么吗?

您好,很遗憾,这不会产生正确的结果。(FindTime’(471021))返回$1=(7-1)。(FindTime’(41018-2))给出了一个非常奇怪的错误。但是,在这之前,为什么要使用负数呢?您的
iPrime
是否正确使用了它们(和1)?首先调试它。这里是链接。我希望它是正确的。我以前没有使用过ideone.com,
(recIsPrime-1)
返回什么?和
(recIsPrime 1)
?您不能编辑它吗?我指的是输入和输出。