您的位置:首页 > 其它

P17 (*) Split a list into two parts; the length of the first part is given.

2016-01-16 10:04 447 查看

问题描述

Do not use any predefined predicates(functions).

sash> (split '(a b c d e f g h i k) 3)
sash> ((a b c) (d e f g h i k))


题目要求“自己动手,丰衣足食“。

解法

尾递归实现

(define split
(lambda (ls n)
(let f ([i 1]
[ls1 '()]
[ls2 ls])
(cond
[(> i n) (list (reverse ls1) ls2)]
[else (f (+ i 1)
(cons (car ls2) ls1)
(cdr ls2))]))))


上面用到了
reverse
,貌似不满足题目要求。

普通递归实现

将上面
ls1
的累积过程改成普通递归形式。在一次遍历实现,需要借助复杂的控制才能实现。如果两次遍历,第一次遍历得到前n个元素的列表,第二次得到其余元素的列表,两次结果cons得到最终结果。

目前没想到满意的方案,暂为空


CPS实现

ls1
累积前n个元素,
ls2
累积其余的元素。

(define split-2
(lambda (ls n k)
(let f ([i 1]
[s ls]
[k k])
(cond
[(null? s) (k '() '())]
[(<= i n) (f (+ i 1) (cdr s)
(lambda (ls1 ls2)
(k (cons (car s) ls1)
ls2)))]
[else (f (+ i 1) (cdr s)
(lambda (ls1 ls2)
(k ls1 (cons (car s) ls2))))]))))
(define return
(lambda (ls1 ls2)
(list ls1 ls2)))

(define split
(lambda (ls n)
(split-2 ls n return)))


CPS方式特别适合在函数中收集多个中间结果的情况,这里收集了
ls1
ls2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lambda lisp 99 CPS