Нужна подсказка по домашнему заданию, в котором нужно добавить цифры в список определенным образом - PullRequest
1 голос
/ 30 января 2020

Это домашний вопрос

Функция принимает в качестве параметра список, который может содержать столько слоев, сколько необходимо, например, подсписки. Например, '(a ( 1 b 3)) или '((a 3 5) (b (3 1) 4)). Выходные данные имеют ту же структуру списка входных данных (это означает, что подсписки поддерживаются), но автомобиль каждого списка является суммой всех чисел в списке. И все другие нечисленные значения c отбрасываются. В качестве примера выходных данных рассмотрим '((a 3 5) (b (3 1) 4)), на выходе должно быть' (16 (8) (8 (4))). Кроме того, используйте только инструкции / операции схемы basi c, например + - * /, car, cdr, cons, append, null ?, number ?, if / else, cond, et c .. Cannot Use вспомогательный метод .

Пока это мой код, который иногда частично выполняет свою работу. Но мне очень трудно понять, как получить сумму из подсписков, чтобы сложить в одном месте в машине из крайнего списка.

(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)))) '())])))

Я уже потратил несколько часов на это, но не вполне может * gr asp, как правильно подойти к проблеме, возможно, потому что это моя первая неделя использования схемы :(. Любая помощь приветствуется.

Кроме того, я не могу использовать вспомогательный метод. Все необходимо выполнить внутри одной функции в рекурсивном стиле. letrec также не допускается.

1 Ответ

1 голос
/ 30 января 2020

Чтобы упростить жизнь, вы должны смоделировать данные. Поскольку типов нет, мы можем сделать это неформально.

Какова структура ввода?

Мы можем смоделировать его как «Определения данных» из Как разрабатывать программы . Прочтите раздел «Переплетенные данные», потому что наше определение данных похоже на определение 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))))

Структура программы должна соответствовать структуре данных.

Таким образом, мы определяем «шаблон» по нашим данным. Он различает и разлагает каждую информацию на пункты. Это далее деструктурирует права пункта.

; 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 : Ваш HW просит вас выполнить несколько задач:

  1. удалить символы
  2. суммировать числа
  3. cons сумма в каждом списке

Не пытайтесь делать все в одной функции. Делегируйте в несколько вспомогательных функций / обходов.

Примечание 2 : Я не моделировал тип вывода. Это то же самое, что и тип ввода, за исключением того, что Symbol больше не является атомом.

...