在尝试解决 Euler Project 问题 7 时方案错误类型参数
scheme wrong-type-argument in attempted solution to Euler Project problem 7
我一直在努力解决 seventh Euler Project problem。我的程序如下所示:
(define (add-prime c)
(define (smallest-divisor n) (find-divisor n 2))
(define (find-divisor n test-divisor)
(cond
((> (* test-divisor test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else
(find-divisor n (+ test-divisor 1)))))
(define (divides? a b) (= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(if (prime? (+ c 1))
(+ c 1)
(add-prime (+ c 1))))
(define (pv v c)
(if (= c (vector-length v))
v
(begin
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
(pv v (+ c 1)))))
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display v))
输出如下所示:
In procedure add-prime:
In procedure +: Wrong type argument in position 1: #<unspecified>
我很困惑。 add-prime
程序本身运行正常,只是当我将它组合起来创建一个包含 10,002 个素数的向量时,它 returns 这个错误。
我认为您的代码中有错别字:
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display prime-vec)) ;; here you want to print the vector
如果我在 DrScheme
中 运行 这个程序,它会给出以下结果,这看起来有点不可思议:
#(2 0 0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 ...)
您仅在地址 0
处初始化向量
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
然后你继续从地址 3
开始填充它
(pv prime-vec 3)
=
(let ((v prime-vec) (c 3))
....
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
....
=
....
(vector-set! prime-vec 3
(add-prime (vector-ref prime-vec 2)))
....
但是您还没有在地址 2
处初始化向量的内容。
Racket 显然将值 0
用于未初始化的地址,但您的实现显然不是,而是那里有 #<unspecified>
,导致错误。
从地址 1
而不是 3
开始填充向量,它应该可以修复错误。
附带说明一下,add-prime
实际上是 next-prime
。命名很重要,好的命名可以减少认知负担。
我一直在努力解决 seventh Euler Project problem。我的程序如下所示:
(define (add-prime c)
(define (smallest-divisor n) (find-divisor n 2))
(define (find-divisor n test-divisor)
(cond
((> (* test-divisor test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else
(find-divisor n (+ test-divisor 1)))))
(define (divides? a b) (= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(if (prime? (+ c 1))
(+ c 1)
(add-prime (+ c 1))))
(define (pv v c)
(if (= c (vector-length v))
v
(begin
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
(pv v (+ c 1)))))
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display v))
输出如下所示:
In procedure add-prime:
In procedure +: Wrong type argument in position 1: #<unspecified>
我很困惑。 add-prime
程序本身运行正常,只是当我将它组合起来创建一个包含 10,002 个素数的向量时,它 returns 这个错误。
我认为您的代码中有错别字:
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display prime-vec)) ;; here you want to print the vector
如果我在 DrScheme
中 运行 这个程序,它会给出以下结果,这看起来有点不可思议:
#(2 0 0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 ...)
您仅在地址 0
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
然后你继续从地址 3
(pv prime-vec 3)
=
(let ((v prime-vec) (c 3))
....
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
....
=
....
(vector-set! prime-vec 3
(add-prime (vector-ref prime-vec 2)))
....
但是您还没有在地址 2
处初始化向量的内容。
Racket 显然将值 0
用于未初始化的地址,但您的实现显然不是,而是那里有 #<unspecified>
,导致错误。
从地址 1
而不是 3
开始填充向量,它应该可以修复错误。
附带说明一下,add-prime
实际上是 next-prime
。命名很重要,好的命名可以减少认知负担。