Skip to content

Commit 5f088a0

Browse files
committed
Add solution for exercise 3-24
1 parent 027781e commit 5f088a0

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-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-
- 章节三: 23/82
28+
- 章节三: 24/82
2929
- 章节四: TODO
3030
- 章节五: TODO
3131
* 运行

chapter3/exercise3-24.rkt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#lang racket
2+
3+
(define (make-table same-key?)
4+
(let ((local-table (mcons '*table* '())))
5+
(define (assoc key records)
6+
(cond ((null? records) false)
7+
((same-key? key (mcar (mcar records)))
8+
(mcar records))
9+
(else (assoc key (mcdr records)))))
10+
11+
;;; O(N)
12+
(define (lookup key)
13+
(let ((record (assoc key (mcdr local-table))))
14+
(if record
15+
(mcdr record)
16+
false)))
17+
18+
(define (insert! key value)
19+
(let ((record (assoc key (mcdr local-table))))
20+
(if record
21+
(set-mcdr! record value)
22+
(set-mcdr! local-table (mcons (mcons key value) (mcdr local-table)))))
23+
'ok)
24+
25+
(define (dispatch m)
26+
(cond ((eq? m 'lookup-proc) lookup)
27+
((eq? m 'insert-proc!) insert!)
28+
(else (error "Unknown operation -- TABLE" m)))
29+
)
30+
dispatch
31+
))
32+
33+
34+
(module+ test
35+
(require rackunit)
36+
37+
(test-case "Test for basic table operation with equal?"
38+
(define op-table (make-table equal?))
39+
(define get (op-table 'lookup-proc))
40+
(define put (op-table 'insert-proc!))
41+
(check-false (get 'no-exist-key))
42+
(put 'name 'White)
43+
(check-equal? (get 'name) 'White)
44+
)
45+
46+
(test-case "Table with numeric tolerance comparison"
47+
(define (within-tolerance? tol)
48+
(lambda (x y) (< (abs (- x y)) tol)))
49+
50+
(define num-table (make-table (within-tolerance? 0.1)))
51+
(define num-get (num-table 'lookup-proc))
52+
(define num-put (num-table 'insert-proc!))
53+
54+
(num-put 1.0 'value-at-1.0)
55+
(check-equal? (num-get 1.05) 'value-at-1.0)
56+
(check-false (num-get 1.2)))
57+
58+
(test-case "Case-insensitive string keys"
59+
(define (case-insensitive=? a b)
60+
(and (string? a) (string? b)
61+
(string-ci=? a b)))
62+
63+
(define str-table (make-table case-insensitive=?))
64+
(define str-get (str-table 'lookup-proc))
65+
(define str-put (str-table 'insert-proc!))
66+
67+
(str-put "Hello" 'value-for-hello)
68+
(check-equal? (str-get "HELLO") 'value-for-hello)
69+
(check-false (str-get "Goodbye")))
70+
)

0 commit comments

Comments
 (0)