Skip to content

Commit 349e2b5

Browse files
committed
Add implementation of exercise 3-63 and 3-64
1 parent d1deed3 commit 349e2b5

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

README.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
习题完成情况:
2626
- 章节一: 43/46
2727
- 章节二: 88/97
28-
- 章节三: 58/82
28+
- 章节三: 60/82
2929
- 章节四: TODO
3030
- 章节五: TODO
3131
* 运行

chapter3/exercise3-63.org

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#+LATEX_CLASS: ramsay-org-article
2+
#+LATEX_CLASS_OPTIONS: [oneside,A4paper,12pt]
3+
#+AUTHOR: Ramsay Leung
4+
5+
#+DATE: 2025-07-29 Tue 23:44
6+
7+
原始版本:
8+
9+
#+begin_src scheme
10+
(define (sqrt-stream x)
11+
(let ((guesses (cons-stream
12+
1.0
13+
(stream-map (lambda (guess)
14+
(sqrt-improve guess x))
15+
guesses))))
16+
guesses))
17+
#+end_src
18+
19+
Louis 的简单版本:
20+
21+
#+begin_src scheme
22+
(define (sqrt-stream x)
23+
(cons-stream
24+
1.0
25+
(stream-map (lambda (guess)
26+
(sqrt-improve guess x))
27+
(sqrt-stream x))))
28+
#+end_src
29+
30+
两者最大的区别就是原始版本有局部变量 =guesses=, 被定义后就在整个流中共享,这意味着每个值只好被计算一次,所以原始版本的时间复杂度是 =O(N)=
31+
32+
而 Louis 版本每次创建流都需要递归访问 =sqrt-stream=, 就需要每次创建流,也就意味着计算第 =n= 个元素就需要重新计算前 =n-1= 个元素,这与未优化的 =fibs= 数列一样,时间复杂度是 =O(2^N)=
33+
34+
无 =memo-proc= 优化的话,原始版本依然高效,因为都指向同一个流,时间复杂度还是 =O(N)=; 而 Louis 版本效率会更差,还会重复计算,依然是指数级,但是效率更差。
35+

chapter3/exercise3-64.rkt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#lang racket
2+
(require "stream.rkt")
3+
(require "iteration-stream.rkt")
4+
5+
(define (stream-limit s tolerance)
6+
(if (or (stream-null? s) (stream-null? (stream-cdr s)))
7+
(error "The given stream contains less than 2 consecutive items " s)
8+
(let ((first (stream-car s))
9+
(second (stream-car (stream-cdr s))))
10+
(if (<= (abs (- first second)) tolerance)
11+
second
12+
(stream-limit (stream-cdr s) tolerance)))))
13+
14+
(define (sqrt x tolerance)
15+
(stream-limit (sqrt-stream x) tolerance))
16+
17+
(module+ test
18+
(require rackunit)
19+
20+
(test-case "Test for stream-limit"
21+
(check-equal? (sqrt 2 0.5) 1.5)
22+
(check-equal? (sqrt 2 0.1) 1.4166666666666665)
23+
(check-equal? (sqrt 2 0.01) 1.4142156862745097)
24+
(check-equal? (sqrt 2 0.0001) 1.4142135623746899)
25+
(check-equal? (sqrt 2 0.0000000001) 1.414213562373095)
26+
(check-equal? (sqrt 4 0) 2.0)
27+
)
28+
)

chapter3/iteration-stream.rkt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#lang racket
2+
(require "stream.rkt")
3+
4+
(define (average x y)
5+
(/ (+ x y) 2))
6+
7+
(define (sqrt-improve guess x)
8+
(average guess (/ x guess)))
9+
10+
(define (sqrt-stream x)
11+
(define guesses
12+
(cons-stream 1.0
13+
(stream-map (λ (guess)
14+
(sqrt-improve guess x))
15+
guesses)))
16+
guesses)
17+
18+
(provide sqrt-stream)

0 commit comments

Comments
 (0)