|
发表于 2007-12-14 01:38:28
|
显示全部楼层
;first, the recursive way, redundant work, very slow
(define (fr n)
(define (c n)
(cond ((< n 1) 0)
(else (+ (c (/ n 10))
(if (= (remainder (floor n) 10) 1)
1
0)))))
(if (< n 10)
1
(+ (fr (- n 1)) (c n))))
;second the tail-recursive way (the iterative way)
;much more efficient
(define (ff n)
(define (c n result)
(cond ((< n 1) result)
(else (let ((delta (remainder (floor n) 10)))
(c (/ n 10) (+ result (if (= delta 1) 1 0) ))))))
(define (cc n) (c n 0))
(define (f n s)
(if (< n 10)
s
(f (- n 1) (+ s (cc n)))))
(f n 1))
;But, still, the above way is not the best way
;Here is a more efficient way to do it.
;With a little analysis of this problem, it can be seen that each bit will
;contribute 10% of 1, well roughly.
;take the number "abcd", if d > 1, then there's "ab(c+1)0"*10% 1 in the least
;significant bit. if c > 1, then there's "a(b+1)00"*10% 1 in the second least
;significant bit, so on and so forth.
;But, whenever there is digit "1", it's a special case and need to be delt with
;serparately.
(define (the-best-f n s c)
(let* ((rest (floor (/ n (expt 10 c))))
(lsb (remainder rest 10)))
(if (< n (expt 10 c))
s
(the-best-f n
(cond ((= lsb 0) (+ s (* rest (expt 10 (- c 1)))))
((= lsb 1) (+ 1 s (remainder n (expt 10 c))
(* 0.1 (floor (/ rest 10)) (expt 10 (1+ c)))))
(else (+ s (* 0.1 (+ 1 (floor (/ rest 10))) (expt 10 (1+ c))))))
(1+ c)))))
(define (best-ff n)
(the-best-f n 0 0))
(define (findit n)
(if (not (= (best-ff n) n))
(findit (+ 1 n))
n))
-------------------------------
没人用scheme, 我就给一个用scheme的好了 |
|