首页 > 解决方案 > 需要一个关于要求以特定方式在列表中添加数字的家庭作业问题的提示

问题描述

这是一个家庭作业问题

该函数接受一个列表作为参数,该列表可以根据需要包含与子列表一样多的层。例如,'(a (1 b 3)) 或'((a 3 5) (b (3 1) 4))。输出与输入具有相同的列表结构(意味着维护子列表),但每个列表的汽车是列表中所有数字的总和。并且所有其他非数字值都被丢弃。作为示例输出,考虑'((a 3 5) (b (3 1) 4)),输出应为'(16 (8) (8 (4)))。此外,只能使用基本的方案指令/操作,例如 + - * /、car、cdr、cons、append、null?、number?、if/else、cond 等。不能使用辅助方法

到目前为止,这是我拥有的代码,有时可以部分完成这项工作。但是我很难弄清楚如何从子列表中获取总和,以便在最外列表的汽车的一个位置加起来。

(define partialsums*
  (lambda (lis)
    (cond
      [(null? lis) '(0)]
      [(list? (car lis)) (cons (partialsums* (car lis)) (if (not (null? (cdr lis))) (partialsums* (cdr lis)) '()))]
      [(number? (car lis)) (cons (+ (car lis) (car (partialsums* (cdr lis)))) '())]
      [else (cons (+ 0 (car (partialsums* (cdr lis)))) '())])))

我已经为此花费了几个小时,但无法完全掌握如何正确解决问题,可能是因为这是我使用方案的第一周:(。感谢任何帮助。

另外,我不能使用辅助方法。一切都需要在一个函数中以递归方式完成。letrec也不被允许。

标签: schemeracket

解决方案


为了让生活更轻松,您应该对数据进行建模。由于没有类型,我们可以非正式地执行此操作。

输入的结构是什么?

我们可以将其建模为“如何设计程序”中的“数据定义” 。阅读“交织数据”部分,因为我们的数据定义类似于S 表达式的定义。

; A NestedElem is one of:
; - Atom
; - NestedList

; An Atom is one of:
; - Number
; - Symbol

; A NestedList is one of
; - '()
; - (cons NestedElem NestedList)

我们可以定义一个atom?谓词来帮助我们区分程序中数据类型的子句。

; Any -> Boolean
; is `a` an atom?
(define atom?
  (lambda (a)
    (or (number? a)
        (symbol? a))))

程序的结构应与数据的结构相匹配。

所以我们在数据上定义了一个“模板”。它将每个数据区分并分解为子句。它进一步解构了一个子句的 rhs。

; NestedElem -> ...
(define nested-elem-template
  (lambda (ne)
    (cond
      [(atom? ne) ...]
      [else ...])))

; Atom -> ...
(define atom-template
  (lambda (atom)
    (cond [(number? atom) ...]
          [(symbol? atom) ...])))

; NestedList -> ...
(define nested-list-template
  (lambda (nl)
    (cond [(null? nl) ...]
          [else (... (car nl)... (cdr nl))])))

我们肯定对数据了解得更多。(car nl)nested-list-template是 NestedElem 类型。因此,我们可以...通过调用处理此类数据的模板来填充一些 s。同样,我们可以将递归调用包装在我们知道的数据类型的表达式周围。

; NestedElem -> ...
(define nested-elem-template
  (lambda (ne)
    (cond
      [(atom? ne) (atom-template ne)]
      [else (nested-list-template ne)])))

; Atom -> ...
(define atom-template
  (lambda (atom)
    (cond [(number? atom) ...]
          [(symbol? atom) ...])))

; NestedList -> ...
(define nested-list-template
  (lambda (nl)
    (cond [(null? nl) ...]
          [else (... (nested-elem-template (car nl))
                     ... (nested-list-template (cdr nl)))])))

现在我们可以“填空”了。

我们可以对这个数据结构进行“过滤”、“映射”和“折叠”。所有这些都可以使用模板作为脚手架来定义。

注意 1:您的硬件要求您执行多项任务:

  1. 删除符号
  2. 总结数字
  3. cons每个列表的总和

不要试图在一个函数中完成所有事情。委托给多个辅助函数/遍历。

注2:我没有模拟输出类型。它与输入类型相同,只是 Symbol 不再是原子。


推荐阅读