[英]List of prime numbers from 2 to n (scheme)
我正在嘗試創建一個過程,以建立從2到任意數字n的素數列表。 當然,這需要反復進行,但是我不完全知道自己在做什么錯。
(define (list-2-to-n n)
(define (iter n result)
(if (= n 0)
result
(if (< n 2)
'()
(if (= (remainder n 3) 0)
(list-2-to-n (- n 1))
(if (even? n)
(list-2-to-n (- n 1))
(iter (- n 1) (cons n result)))))))
(iter n '()))
每當測試用例通過過程時,它總是返回()
我做錯了。
讓我們來看看。 首先,您的縮進有誤導性。 它確實應該正確反映代碼的結構:
(define (list-2-to-n-0 n) ; a global function
(define (iter n result) ; an internal function
(if (= n 0)
result
(if (< n 2) ; **else**
'()
(if (= (remainder n 3) 0)
(list-2-to-n (- n 1))
(if (even? n) ; **else**
(list-2-to-n (- n 1))
(iter (- n 1) (cons n result)))))))
(iter n '()))
如果沒有,至少您應該在替代條款中清楚地標記一些注釋。
現在,您測試輸入數字是否可以被2或3整除,並以完全相同的方式響應。 確實應該將這兩種情況合而為一。 同樣,我們可以在這里使用cond
,而不是那么多的if
嵌套:
(define (list-2-to-n-1 n) ; a global function
(define (iter n result) ; an internal function
(cond
((= n 0) result)
((< n 2) '())
((or (= (remainder n 2) 0) (= (remainder n 3) 0))
(list-2-to-n (- n 1)) ; calling a global function, and
(else ; returning its result
(iter (- n 1) ; calling internal function, and
(cons n result))))) ; returning its result
(iter n '()))
在此處調用全局函數意味着重新開始整個過程,它將使用()
的初始累加器參數調用其 iter
器。 對於任何大於0的n
初始值,您實際上想得到的n==0
結果返回情況實際上是無法達到的,因為首先會遇到n < 2
的情況,並且將返回( ()
(恰好是觀察到的行為)。
您不應該重新開始,即您應該始終調用內部函數。 您應該修復基本情況。 最后但並非最不重要的一點是,僅用5進行2或3的除數檢查是不夠的,因此讓我們在此處編寫isPrime
,然后在以后實現:
(define (list-2-to-n-1 n) ; a global function
(define (iter n result) ; an internal function
(cond
((< n 2) result)
((not (isPrime n))
(iter (- n 1) result)) ; calling internal function, without
(else ; altering the accumulator
(iter (- n 1) ; calling internal function,
(cons n result))))) ; altering the accumulator
(iter n '()))
isPrime
需要嘗試將n
除以2,3,...不需要嘗試除以2以上的任何偶數,只要賠率就足夠了。 不需要嘗試任何可能的除數d
,使得d * d > n
,因為如果n = f * d, f <= d
則f*d <= d*d
即n <= d*d
。
當然,嘗試除以9、15、77之類的任何組合也是多余的-如果其中任何一個除以n
則它們的主要因子3、5、7、11之一也將其除,我們將更早地檢測到它們。 因此,實際上,僅嘗試除以質數就足夠了。 為此,您需要重組代碼,以便它以升序構建其素數列表,並使用其前綴部分不大於sqrt(k)
來測試每個候選k
。
這稱為試驗分割算法。 然后有一個更快的Eratosthenes篩子 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.