1.对于没有赋值语句的程序如何实现参数改变
(1)递归调用改变参数
比如,我要实现检验输入的参数begin是一个偶数还是奇数,如果是奇数进行下一步,如果是偶数就+1将其设置为奇数。
程序如下:
(define (search-for-primes begin counter)
(if (= (remainder begin 2) 0)
(search-for-primes (+ begin 1) counter) ----------------①
(start-test begin counter (runtime))))
这里将begin+1的目的是①中递归调用search-for-primes函数实现的,因为这里还没有学到Scheme的赋值语句。
如果可以像C++一样对形式参数直接赋值,程序完全就能改地更清晰:
(define (search-for-primes begin counter)
(change-to-odd begin)
(start-test begin counter (runtime)))
(define (change-to-odd x)
(if (= (remainder x 2) 0)
(+ x 1)
x))
可惜的是,没有赋值的时候,(change-to-odd begin)不能直接改变begin的值,当然我们可以有其他办法。
(2)仍然要借助函数调用才能实现,不过不需递归了。
(define (search-for-primes begin counter)
(start-test (change-to-odd begin) counter (runtime))) -------------②
(define (change-to-odd x)
(if (= (remainder x 2) 0)
(+ x 1)
x))
如②中所示,由于change-to-odd函数可以返回改变成的值,我们可以这样使用。当然也可以采用这种方式。
(define (search-for-primes begin counter)
(define new-begin (change-to-odd begin))
(start-test new-begin counter (runtime)))
注:之所以能够像(2)这样,是因为整个函数的其他功能还是要靠start-test这个函数实现,并且有一个与search-for-primes相同的参数。
所以有(2)这样的方式,但是如果没有这种情况要实现上述目标,就只有通过先判断然后改变参数递归调用search-for-primes实现了。
2.将只需进行一次的操作与其余操作分离
整个search-for-primes的功能是给定一个初始值begin,以及个数counter
给出从begin开始的counter个素数。
由于素数除了2之外肯定是奇数,所以没必要每次再去调用(prime? ),在确保其实奇数之后,每次增加2,就可以确保每次只检测奇数了。
(define (search-for-primes begin counter)
(if (= (remainder begin 2) 0)
(search-for-primes (+ begin 1) counter)
(start-test begin counter (runtime))))
所以可以先对于begin进行处理,将之后的功能封装到另一个函数中。