我是一名方案新手,我现在正在阅读SICP。我在网站上发现了一个问题。我花了2天的时间思考它但仍然不知道你们能帮忙吗?
问题如下:
计算机科学中的一项常见任务是在数据集中查找模式的实例。在这 问题,您将编写一个返回索引列表的过程(find-sublist space子列表) 按顺序在空间中的子列表的所有实例的开始。请注意,子列表的实例可以 如[]给出的一个例子中的重叠。如果空间包含列表,则无需查找 空间列表中的子列表,如以下[ *]中的一个示例所示。你可能会认为 子列表不为空。
Examples:
(find-sublist '(7 1 2 3 4 1 2 1 2) '(1 2)) ; should return '(2 6 8)
(find-sublist '(“a” “b” “c” “b” “d”) '(“d”)) ; should return '(5)
(find-sublist '((1 2) (3 4) (5 . 6) 7 #f) '((3 4) (5 . 6))) ; should return '(2)
(find-sublist '(1 1 1 2 1) '(1 1)) ; [*] should return '(1 2)
(find-sublist '(9 1 2 3 (5 1 2 3) 1 2 3) '(1 2 3)) ; [**]should return '(2 6)
(find-sublist '() '(#t #f #f)) ; should return '()
答案 0 :(得分:3)
我会给你一些提示,让你自己找到答案,填写空白。第一步是将问题分成两部分,首先是一个谓词,告诉sublst
是否在lst
,从lst
的第一个位置开始:
(define (sublist? lst sublst)
(cond (<???> <???>) ; if sublst is empty return true
((and <???> ; if lst is not empty and
<???>) ; the first element is equal in both lists
(sublist? <???> <???>)) ; advance recursion over both lists
(else <???>))) ; otherwise return false
现在主要程序:这个程序检查space
中的每个位置是否有从那里开始的子列表(使用前面的程序)。如果是这样,建立一个列表作为当前索引的元素传递。请注意,我们需要在额外参数中跟踪当前索引:
(define (find-sublist space sublist)
(let loop ((space space) ; initialize iteration variables
(idx 1))
(cond (<???> <???>) ; if space is empty return the empty list
; if the list starting at current position is the sublist
((sublist? space sublist)
(cons <???> ; cons current index, advance recursion
(loop <???> <???>))) ; over the list and increment index
(else ; otherwise just advance the recursion
(loop <???> <???>))))) ; same as before
答案 1 :(得分:0)
你问自己一个问题:我的列表的第一个元素是否与模式匹配?如果是,请记录索引。如果您解决了该问题,则将相同的逻辑应用于列表的其余部分。这是一个简单的解决方案。
(define (find-sublist list sub)
(define (sublist? list sub)
(or (null? sub)
(and (not (null? list))
(equal? (car sub) (car list))
(sublist? (cdr list) (cdr sub)))))
(let walking ((list list) (index 1) (indices '()))
(if (null? list)
(reverse indices)
(walking (cdr list)
(+ 1 index)
(if (sublist? list sub)
(cons index indices)
indices)))))
这使用了一种称为“尾递归”的技术,使其在计算上等效于迭代。