Схема сумма списка - PullRequest
       32

Схема сумма списка

3 голосов
/ 05 февраля 2012

Во-первых, это домашняя работа, но я просто ищу подсказку или псевдокод о том, как это сделать.

Мне нужно сложить все элементы в списке, используя рекурсия .Тем не менее, он должен вернуть пустой набор, если он обнаружит в списке что-то, что не является числом.Вот моя попытка:

(DEFINE sum-list
  (LAMBDA (lst)
    (IF (OR (NULL? lst) (NOT (NUMBER? (CAR lst))))
      '()
      (+
        (CAR lst)
        (sum-list (CDR lst))
      )
    )
  )
)

Это не удается, потому что он не может добавить пустой набор к чему-то другому.Обычно я просто возвращаю 0, если это не число, и продолжаю обрабатывать список.

Ответы [ 5 ]

4 голосов
/ 05 февраля 2012

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

Что-то в этом духе (заполните пробелы!):

(define sum-list
  (lambda (lst acc)
    (cond ((null? lst) ???)
          ((not (number? (car lst))) ???)
          (else (sum-list (cdr lst) ???)))))

(sum-list '(1 2 3 4 5) 0)
> 15

(sum-list '(1 2 x 4 5) 0)
> ()
3 голосов
/ 06 февраля 2012

Я бы пошел на это:

(define (mysum lst)
  (let loop ((lst lst) (accum 0))
    (cond
      ((empty? lst) accum)
      ((not (number? (car lst))) '())
      (else (loop (cdr lst) (+ accum (car lst)))))))
2 голосов
/ 05 февраля 2012

Ваша проблема в том, что вам нужно использовать cond, а не в том случае, если есть три возможных ветви, которые вам нужно рассмотреть. Первый - если вы столкнулись с ненулевым числом, второй - когда вы сталкиваетесь с концом списка, а третий - когда вам нужно вернуться к следующему элементу списка. Первая проблема заключается в том, что вы комбинируете регистр без нумерации и регистр пустого списка, которые должны возвращать разные значения. Рекурсивный регистр в основном корректен, но вам придется проверить возвращаемое значение, поскольку рекурсивный вызов может вернуть пустой список.

1 голос
/ 06 февраля 2012

Поскольку я не достаточно умен, чтобы понять, как сделать это с помощью одной функции, давайте скажем прямо:

#lang racket

; This checks the entire list for numericness
(define is-numeric-list?
  (lambda (lst)
    (cond
      ((null? lst) true)
      ((not (number? (car lst))) false)
      (else (is-numeric-list? (cdr lst))))))

; This naively sums the list, and will fail if there are problems
(define sum-list-naive
  (lambda (lst)
    (cond
      ((null? lst) 0)
      (else (+ (car lst) (sum-list-naive (cdr lst)))))))

; This is a smarter sum-list that first checks numericness, and then
; calls the naive version.  Note that this is inefficient, because the
; entire list is traversed twice: once for the check, and a second time
; for the sum.  Oscar's accumulator version is better!
(define sum-list
  (lambda (lst)
    (cond
      ((is-numeric-list? lst) (sum-list-naive lst))
      (else '()))))

(is-numeric-list? '(1 2 3 4 5))
(is-numeric-list? '(1 2 x 4 5))

(sum-list '(1 2 3 4 5))
(sum-list '(1 2 x 4 5))

Выход:

Welcome to DrRacket, version 5.2 [3m].
Language: racket; memory limit: 128 MB.
#t
#f
15
'()
> 

Я подозреваю, что ваша домашняя работа ожидает чего-то большего академического .

0 голосов
/ 05 февраля 2012

Попробуйте сделать функцию "is-any-nonnumeric" (используя рекурсию); тогда вы просто (или (is-any-numeric list) (список сумм)) tomfoolery.

...