SICP Table

这篇博客主要讨论了SICP中的表处理,包括如何生成keylist作为argument的过程,以及利用递归思路实现lookup功能。在测试过程中发现了一些问题,通过修改逻辑解决了这些问题。此外,文章还介绍了如何利用树的结构实现有序表,但由于限制仅实现了针对一维表的实现,二维及以上需要额外处理。博主创建了树节点的selector和mutator,并将这些应用于insert和lookup操作。
摘要由CSDN通过智能技术生成

主要叙述一下习题中的两个

其一为生成keylist为argument的过程

这个操作显然又是一种递归思路,我们只需不断生成子表直到最后一个key 但是与textbook中不同的是

textbook中由于是two dimensional table 所以直接将首项加入子表中

而我们生成的仅仅是子表,故只需(list (car keylist))即可

同样,我们类似思路可以实现lookup 

完成以上后我们进行测试,结果会有点bug 例如 (put '(a) 1) (put '(a b) 2)

我们(get '(a))将得到值1 和子表 (b 2) 这显然不是我们要的结果,但是非常接近

我们对结果打个补丁,将(not pair? )进行输出即可

其二为利用树的结构实现有序表

这个一开始看到实在有点懵逼,所以直接重写了一个,遗憾是只实现了一维表,原因是因为二维即以上需要再加一个空作为子树(key-2)的指针

首先,我们要创建树节点(key value left-node right-node)的selectors 以及mutators 其次我们要创建树addnode looknode等操作

最后将这些放入我们的insert lookup中即可

以下是实现代码

(define same-key? eq?)
(define (find-not-pair list) 
	(cond	((null? list) ())
		((not (pair? list)) list)
		((not (pair? (car list))) (car list))
		(else (find-not-pair (cdr list)))))
(define (last list) (if (null? (cdr list)) (car list) (last (cdr list))))
(define (make-table same-key?)
	(let	((table (list '*table*)))
		(define (insert keylist value)
			(define (iter keylist table)
				(cond	((null? (cdr keylist)) table)
					(else 
						(let	((subtable (assq (car keylist) (cdr table))))
							(if	(null? subtable)
								(begin
									(set-cdr! table (cons (list (car keylist)) (cdr table)))
									(iter (cdr keylist) (cadr table)))
								(iter (cdr keylist) subtable))))))
			(let	((subtable (iter keylist table)))
				(let	((record (assq (last keylist) (cdr subtable))))
					(if	(null? record)
						(set-cdr! subtable (cons (cons (last keylist) value) (cdr subtable)))
						(set-cdr! record value))))
			'ok)
		(define (lookup keylist)
			(define (iter keylist table)
				(if	(null? (cdr keylist))
					table
					(let	((subtable (assq (car keylist) (cdr table))))
						(if	(null? subtable)
							()
							(iter (cdr keylist) subtable)))))
			(let	((subtable (iter keylist table)))
				(if	(null? subtable)
					()
					(let	((record (assq (last keylist) (cdr subtable))))
						(if	(null? record)
							()
							(find-not-pair (cdr record)))))))
		(define (assq key records)
				(cond	((null? records) ())
					((not (pair? records)) ())
					((same-key? key (caar records)) (car records))
					(else (assq key (cdr records)))))
		(lambda (m) 
			(cond	((eq? m 'lookup) lookup)
				((eq? m 'insert) insert)
				(else (error "Error Operation --TABLE" m))))))
(define tmp-table (make-table same-key?))
(define put (tmp-table 'insert))
(define get (tmp-table 'lookup))

;;First I need to implement the one dimensional  ordered  table use tree
(define (make-table)
	;;use a list (key vaule smaller-key bigger-key) as a node
	
	;;Node
	(define (create-node key value)
		(list key value () ()))

	(define (Nodekey node) (car node))
	(define (Nodevalue node) (cadr node))
	(define (NodeSkey node)  (caddr node))
	(define (NodeBkey node) (cadddr node))

	(define (Setvalue node value) (set-car! (cdr node) value ))
	(define (SetSkey node item) (set-car! (cddr node) item ))
	(define (SetBkey node item) (set-car! (cdddr node) item ))
	(define (setKey node key ) (set-car! node key))


	;;Tree Operation
	
	(define (Addnode key value node)
		(cond	((= key (Nodekey node))
				(Setvalue node value))
			((< key (Nodekey node))
				(cond	((null? (NodeSkey node))
						(SetSkey node (create-node key value)))
					((> key (Nodekey (NodeSkey node)))
						(let	((new-node (create-node key value)))
							(SetSkey new-node (NodeSkey node))
							(SetSkey node new-node)))
					(else (Addnode key value (NodeSkey node)))))
			((> key (Nodekey node))
				(cond	((null? (NodeBkey node))
						(SetBkey node (create-node key value)))
					((< key (Nodekey (NodeBkey node)))
						(let	((new-node (create-node key value)))
							(SetBkey new-node (NodeBkey node))
							(SetBkey node new-node)))))))

	(define (LookNode key node)
		(cond	((null? node) ())
			((= key (Nodekey node)) (NodeValue node))
			((< key (Nodekey node)) (LookNode key (NodeSkey node)))
			(else (LookNode key (NodeBkey node)))))
	

	;;Table Tree
	(let	((table (cons '*table* (create-node () ()))))
		(define (insert key value)
		;;Here assume it can be ordered by numerically
			(define (iter node)
				(cond
					((null? (Nodekey node)) (SetKey node key) (Setvalue node value))
					(else (Addnode key value node))))
			(iter (cdr table))
		'ok)
		(define (lookup key)
			(define (iter node)
				(cond
					((null? (Nodekey node)) ())
					(else (LookNode key node))))
			(iter (cdr table)))
		(lambda (m)
			(cond
				((eq? m 'insert) insert)
				((eq? m 'lookup) lookup)
				(else (error "Error Operation -- TABLE" m))))))
(define tmp-table (make-table))
(define put (tmp-table 'insert))
(define get (tmp-table 'lookup))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值