【发布时间】:2019-11-30 23:36:54
【问题描述】:
我正在结合来自伯克利的 2011 年夏季 CS3 课程学习简单计划。我正在努力理解subset / subsequence 程序。收到解决方案代码后,我了解了基本机制,但我很难掌握足够的概念以自己提出解决方案。
谁能给我指出一些可以帮助我更好地理解它的方向?还是自己解释不同?
这是我目前所了解的基础:
因此,在以下过程中,作为prepend 的参数的subsequences 递归调用将word 分解为其基本元素,而prepend 将添加@ 的first 987654329@ 到每个元素。
; using words and sentences
(define (subsequences wd)
(if (empty? wd)
(se "")
(se (subsequences (bf wd))
(prepend (first wd)
(subsequences (bf wd))))))
(define (prepend l wd)
(every (lambda (w) (word l w))
wd))
; using lists
(define (subsequences ls)
(if (null? ls)
(list '())
(let ((next (subsequences (cdr ls))))
(append (map (lambda (x) (cons (car ls) x))
next)
next))))
所以第一个,当输入(subsequences 'word) 时,会返回:
("" d r rd o od or ord w wd wr wrd wo wod wor word)
第二个,当输入(subsequences '(1 2 3))时,会返回:
((1 2 3) (1 2) (1 3) (1) (2 3) (2) (3) ())
所以,正如我所说,这段代码有效。我单独理解代码的每个部分,并且在大多数情况下,它们是如何相互协作的。嵌套递归调用给我带来了麻烦。我只是不完全理解它,无法自己编写这样的代码。任何能够帮助我理解它的东西都将不胜感激。我想我只需要一个新的视角来思考它。
提前感谢任何愿意为我指明正确方向的人。
编辑:
所以第一条评论要求我尝试多解释一下我目前所了解的内容。就是这样:
对于单词/句子过程,我认为它通过第二个出现的递归调用将变量分解为“最基础”的情况(可以这么说)。
然后它基本上是在基本情况的基础上构建的。
我真的不明白为什么首先出现的递归调用需要在那里。
在列表之一中,当我自己编写时,我得到了这个:
(define (subseq lst)
(if (null? lst)
'()
(append (subseq (cdr lst))
(prepend (car lst)
(subseq (cdr lst))))))
(define (prepend i lst)
(map (lambda (itm) (cons i itm))
lst))
使用正确的解决方案,在我看来,列表中的car 会掉线而不会被计算在内,但显然情况并非如此。我不明白这两个递归调用是如何协同工作的。
【问题讨论】:
-
“我理解代码的每个部分,并且在大多数情况下,它们是如何相互配合的。”我建议用你自己的话描述你的内容了解到此为止。这不仅可以帮助您自己整理想法,而且对任何想回答您的问题的人都有很大帮助。 [编辑:将块引用降价调整为引号 -- Baum mit Augen]
-
bf 和 se 不是标准的 Scheme 函数;你能在问题中包含他们的定义吗?
-
我会避免两次调用
(subseq (cdr lst));您可以使用let在变量中捕获它。(let ((scl (subseq cdr lst))) (append scl (prepend (car lst) scl))). -
@Kaz 原来“Simply Scheme Lisp”是googlable。 :)
标签: list recursion scheme lisp sequence