好的,所以我正在尝试编写一个函数来查找列表中两个元素之间的距离,s和t。
例如,如果s = bob且t = pizza:
(d 'bob 'pizza '(bob blah blah pizza))
它将返回:3
这是我到目前为止所做的。
(define dist
(lambda (s t line)
(cond
[(equal? s (car line))
[(equal? t (car (cdr line)))
1]]
[else (add1 (dist s t (cdr line)))])))
出于某种原因,它不起作用。帮助
谢谢!
答案 0 :(得分:3)
问题中的建议代码不起作用,它只是检查列表中的两个元素是否连续。让我们尝试一种不同的方法 - 在较小的子问题中分解问题,首先定义一个返回列表中元素索引的过程,从零开始计算索引:
(define (index-of elt lst)
<???>) ; ToDo
采用上述程序,假设列表中存在s
和t
,t
后出现s
,则很容易找到解决方案问题:
(define dist
(lambda (s t line)
(- (index-of t line)
(index-of s line))))
例如:
(dist 'bob 'pizza '(bob blah blah pizza))
=> 3
要获得额外的功劳,请考虑列表中不存在其中一个或两个元素的情况(因此index-of
应返回指示此值的值,例如#f
),或者{s
1}}出现在列表中的t
之后。
答案 1 :(得分:0)
当你在最后一步拍摄(cdr线)时,即使bob是第一个元素,你也会扔掉bob。
你需要照顾3个,也许4个案例。 s和t匹配前两个元素你做得很好。 其中s匹配而t不需要使用删除了第二个元素的行向递归调用添加1。像(缺点(汽车线)(cdr(cdr line)))。 如果s不匹配,则需要移除线路并重试。 除非你确定s和t都会发生,并且你需要一个终止条件来处理违规行为。
答案 2 :(得分:0)
这是一个解决方案,每次都在列表中搜索's'和't'。当两者都被看到时,返回结果;否则,继续寻找:
(define (dist s t line)
(let looking ((l line) (n 0) (i #f))
(and (not (null? l))
(let ((item (car l)))
(if (or (equal? item s)
(equal? item t))
(if (not i)
(looking (cdr l) (+ n 1) n) ; found first, continue
(- n i)) ; found second, done
(looking (cdr l) (+ n 1) i)))))); continue looking