需要一个作业问题提示,要求以特定方式在列表中添加数字

问题描述 投票:1回答:1

这是一个作业问题

该函数接受一个列表作为参数,可以根据需要包含与子列表一样多的层。例如,'(a(1 b 3))或'((a 3 5)(b(3 1)4) )。输出具有与输入相同的列表结构(这意味着将保留子列表),但是每个列表的car都是列表中所有数字的总和。并丢弃所有其他非数字值。作为示例输出,请考虑'(((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)))) '())])))

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

scheme racket
1个回答
0
投票

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

输入的结构是什么?

我们可以像How to Design Programs中的“数据定义”那样对其建模。阅读“交织数据”部分,因为我们的数据定义与S-expression相似。

; 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。因此,我们可以使用对处理此类数据的模板的调用来填充某些...。同样,我们可以在已知的数据类型的表达式周围包裹递归调用。

; 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不再是原子。

© www.soinside.com 2019 - 2024. All rights reserved.