1

好的,所以我正在尝试编写一个函数来查找列表中两个元素 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)))])))

由于某种原因,它不起作用。帮助?

谢谢!

4

3 回答 3

3

问题中建议的代码不起作用,它只是检查两个元素在列表中是否连续。让我们尝试一种完全不同的方法 - 将问题拆分为更小的子问题,首先定义一个返回列表中元素索引的过程,从零开始计算索引:

(define (index-of elt lst)
  <???>) ; ToDo

有了上述过程,并假设st都出现在列表中并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出现t在列表中之后的情况。

于 2013-03-05T21:59:24.013 回答
0

当您在最后一步中使用(cdr 行)时,即使 bob 是第一个元素,您也会扔掉 bob。

您需要处理 3 个甚至 4 个案例。其中 s 和 t 匹配前两个元素,你做得很好。在哪里 s 匹配,而 t 您不需要使用 line 将 1 添加到递归调用中,并删除了第二个元素。像 (cons (car line) (cdr (cdr line))) 之类的东西。如果 s 不匹配,则需要删除 line 的 car 并重试。除非您确定 s 和 t 都会发生,并且您需要一个终止条件来处理超出范围的问题。

于 2013-03-05T21:52:18.537 回答
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
于 2013-03-05T23:56:12.730 回答