我是计划新手,在调试代码时遇到了一些麻烦。
; returns number of elements in a list
(define (length L)
(cond ((null? L) 0)
(else (+ (length (cdr L)) 1))))
; split the list in half:
; returns ((first half)(second half))
(define (split L)
(cond
((= (length L) 0) (list L L) )
((= (length L) 1) (list L '() ))
(else
(list (sublist L 1 (/ (length L) 2) 1)
(sublist L (+ (/ (length L) 2) 1) (length L) 1)))))
; extract elements start to end into a list
(define (sublist L start end counter)
(cond ((null? L) L)
((< counter start) (sublist (cdr L) start end (+ counter 1)))
((> counter end) '())
(else (cons (car L) (sublist (cdr L) start end (+ counter 1))))))
对我而言,这感觉就像将单个列表拆分为两个子列表一样。可能有一种更简单的方法,所以如果这看起来很麻烦,我会道歉。
无论如何,结果:
Expected: (split '(1 2 3 4 5)) = ('(1 2) '(3 4 5))
Actual: (split '(1 2 3 4 5)) = ('(1 2) '(4 5))
很明显,length
或split
正在失去中间值,但我一次又一次地检查它,似乎失去了中间值。似乎一个简单的解决办法就是摆脱(+ 1)
(+ (/ (length L) 2) 1)
,但这对我来说似乎很直观,因为:
Assume L = '(1 2 3 4 5), (/ (length L) 2) = 2, and (+ (/ (length L) 2) 1) = 3
(sublist L 1 (2) 1) = '(1 2)
(sublist L (3) 5 1) = '(3 4 5)
** I put parens around the 2 and 3 to indicate that they were length calculations.
显然,我所做的假设是错误的,或者我忽略了一些微不足道的事情。
提前致谢!
答案 0 :(得分:6)
你知道乌龟和野兔算法吗?乌龟走在名单上,野兔以双倍的速度奔跑。当野兔到达列表的末尾时,分裂发生在乌龟的位置。这是大部分代码;我会让你弄明白其余的事情:
(define (split xs)
(let loop ((ts xs) (hs xs) (zs (list)))
(if (or (null? hs) (null? (cdr hs)))
(values (reverse zs) ts)
(loop ...))))
这里ts是乌龟要检查的剩余物品清单,hs是野兔要检查的剩余物品清单,而zs是乌龟已经检查过的物品清单,顺序相反。 / p>
请注意,您永远不需要计算输入列表中的项目。
答案 1 :(得分:2)
我不打算为你调试你的代码。相反,这里有一个更简单的split
定义:
(define (split l)
(let ((n (length l)))
(list (take (/ n 2) l)
(drop (+ (/ n 2) (mod n 2)) l))))
为读者练习:实施take
和drop
。后者只是n
的递归,同时在递归情况下取cdr
l
;前者需要稍微努力才能在基本情况下(停止条件)。
答案 2 :(得分:0)
这几乎是你的解决方案(球拍方案):
#lang racket
(define (length lst)
(cond [(empty? lst) 0]
[else (+ (length (rest lst)) 1)]))
(define (first-length lst)
(quotient (length lst) 2))
(define (second-length lst)
(- (length lst) (first-length lst)))
(define (sublist lst start end counter)
(cond [(empty? lst) lst]
[(< counter start) (sublist (rest lst) start end (+ counter 1))]
[(> counter end) '()]
[else (cons (first lst) (sublist (rest lst) start end (+ counter 1)))]))
(define (first-half-of-list lst)
(sublist lst 1 (first-length lst) 1))
(define (second-half-of-list lst)
(sublist lst (second-length lst) (length lst) 1))
(define (split lst)
(cond
[(= (length lst) 0) (list lst lst)]
[(= (length lst) 1) (list lst '())]
[else (list (first-half-of-list lst)
(second-half-of-list lst))]))
(split '(1 2 3 4 5))
=> '((1 2) (3 4 5))
感谢您进行良好的大脑锻炼。 关键时刻是“第二长度”功能。