Recursion Scheme,停止我的递归

Recursion Scheme,停止我的递归,recursion,scheme,Recursion,Scheme,函数firstnprimes应该返回第一个n素数。参数是n素数,nlist一个2-m整数列表。而slist是解决方案列表,最初为空,添加到firstnprimes的每个调用中并重新构造 它的工作原理是从列表中删除第一个数字,然后使用listnumnsprimes从nlist中删除该数字的所有倍数;我知道这很管用。问题是我无法控制这个动作,我认为如果slist的长度等于你想要的素数,那么你就完成了 代码: (define firstnprimes (lambda (n nlist slist)

函数
firstnprimes
应该返回第一个
n
素数。参数是
n
素数,
nlist
一个2-m整数列表。而
slist
是解决方案列表,最初为空,添加到firstnprimes的每个调用中并重新构造

它的工作原理是从列表中删除第一个数字,然后使用
listnumnsprimes
nlist
中删除该数字的所有倍数;我知道这很管用。问题是我无法控制这个动作,我认为如果
slist
的长度等于你想要的素数,那么你就完成了

代码:

(define firstnprimes
  (lambda (n nlist slist)
   (let ((slist (cons (car nlist) slist)))
    (if (zero? n)
        slist
        (firstnprimes (- n 1) (listMinusNonprimes (car nlist) (car nlist) nlist) slist)))))


(define listminusnonprimes
     (lambda (num d lst)
       (if (null? lst)
           '()
           (if (= d (car lst))
               (listminusnonprimes num (+ num d) (cdr lst))
               (cons (car lst) (listminusnonprimes num d (cdr lst)))))))

您对
listminusnonprimes
的定义是错误的。想象一下调用
(listminusnonprimes 3 3'(3 5 7 9 11…)
(因为在删除所有倍数的
2
后会发生这种情况)。现在
3
被删除,递归调用
(listminusnonprimes 6 3'(5 7 9 11…)
,但是
6
不在那里,因此调用不做任何操作,结果是
(3 5 7 9 11…)

我建议使用mod操作实现此功能。

您不需要
(let((slist(cons(car nlist)slist))
。此外,使用append代替cons,如图所示

(define firstnprimes
  (lambda (n nlist slist)
    (if (zero? n)
        slist
        (firstnprimes (- n 1) (listminusnonprimes (car nlist) (car nlist) nlist) (append slist (list (car nlist)))))))
所以

但是,您的实现存在很多问题。首先,列表必须按递增顺序排列。此外,列表必须以素数开头。此外,
nlist
中的素数必须小于或等于
n
(firstnprimes4'(24792136)()=>'(27921)
哪个是错误的

这是一个稍微好一点的概念实现

(define firstnprimes
  (lambda (n nlist slist)
    (if (or (zero? n) (null? nlist))
        slist
        (firstnprimes (- n 1) (listminusnonprimes (car nlist) (car nlist) nlist) (append slist (list (car nlist)))))))


(define listminusnonprimes
     (lambda (num d lst)
       (if (null? lst)
           '()
           (if (< d (car lst))
               (listminusnonprimes num (+ num d) lst)
               (if (= d (car lst))
                   (listminusnonprimes num (+ num d) (cdr lst))
                   (cons (car lst) (listminusnonprimes num (+ num d) (cdr lst))))))))

但是第一个元素仍然必须是素数,尽管

问题出在哪里?递归的终止?从快速浏览的角度看似乎很好。此外,除了长度之外,似乎不需要
n
,这意味着您应该能够在每次递归调用中递减
n
,然后检查
n
是否等于or小于零,而不是一次又一次地计算列表长度。好的,因此每次调用最后一行上的firsnprimes,我都会从n中删除一个,并检查if语句中的值是否为零。看起来不错。虽然我的输出结果是每个数都是2到n(仍然).我想有人能看到problem@BumSkeeter您仍然需要在最后一行将
n
减少1,还有
ListMinusNoPrimes
做什么?为什么要将
(car nlist)
传递两次?ListMinusNoPrimes删除第一个输入数的倍数,增加第二个。因此“2 2列表”将从列表中删除前2个,然后从列表中删除2+2,然后再删除2+2+2,等等。我还更改了代码,以便is检查n是否为零,因为我们每次向列表中添加1,就可以每次将n减量1。像这样?;返回一个基于num removed的非primes列表(定义lmnp(lambda(n list)(if(null?list))“()(如果(=(模(汽车列表)n)0)(lmnp n(cdr列表))(cons(汽车列表)(lmnp n(cdr列表()(()))”)
(define firstnprimes
  (lambda (n nlist slist)
    (if (or (zero? n) (null? nlist))
        slist
        (firstnprimes (- n 1) (listminusnonprimes (car nlist) (car nlist) nlist) (append slist (list (car nlist)))))))


(define listminusnonprimes
     (lambda (num d lst)
       (if (null? lst)
           '()
           (if (< d (car lst))
               (listminusnonprimes num (+ num d) lst)
               (if (= d (car lst))
                   (listminusnonprimes num (+ num d) (cdr lst))
                   (cons (car lst) (listminusnonprimes num (+ num d) (cdr lst))))))))
(firstnprimes 2 '(2 4 7 9 21 36) '()) => '(2 7)
(firstnprimes 3 '(2 4 7 9 21 36) '()) => '(2 7 9)
(firstnprimes 4 '(2 4 7 9 21 36) '()) => '(2 7 9)