2013-09-20 6 views
0

Как написать функцию в схеме, которая суммирует числа во встроенных списках?Как написать функцию SUM на схеме?

т.е. ((1) (2 3) (4) (5 6))

Я написал это просуммировать обычный список:

(define (sum list) 
    (if (null? list) 
     0 
     (+ (car list) (sum (cdr list))))) 

, но я не уверен, как это сделать встроенный.

ответ

3

У вас есть 3 случая:

(define (my-sum lst) 
    (cond 
    ; 1. the list is empty, so finish of by adding 0 
    ([empty? lst]  0) 
    ; 2. the first element is a list, so recurse down on the sublist, then do the rest 
    ([list? (car lst)] (+ (my-sum (car lst)) (my-sum (cdr lst)))) 
    ; 3. add the first element to the sum, then do the rest 
    (else    (+ (car lst)   (my-sum (cdr lst)))))) 

так что вы просто пропавшие средний случай.

Это будет работать независимо от глубины вложенности:

(my-sum '((1) (2 3) (4) (5 6))) 
=> 21 

(my-sum '((1) (2 3) (4) (5 6 (7 8 (9))))) 
=> 45 

Пожалуйста, обратите внимание, что вы не должны использовать имена «сумма» и «список», чтобы не затенять Построенные в процедуры.

+0

Ничего плохого затенения встроенных команд, которые не используются в процедуре, как это не будет течь связыванию вне определения. – Sylwester

+0

@ Sylwester Это сработает, но я считаю, что это плохая практика, но это рано или поздно укусит вас. – uselpa

+0

спасибо большое !!! – Layla

-1

В более функционально

; this sums the elements of a not-embedded list 
(define (sum-list* l) 
    (foldl + 0 l)) 

; this sums the elements of an embedded list 
(define (sum-embedded-list* el) 
    (foldl + 0 (map sum-list* el))) 

Он охватывает случай списка полученного таким образом: ((A1 ... An) (b1 ... млрд) ...), где а и ЛЮ являются атомами. Foldl и map - две важные функции в схеме (и других языках). Если вы не знаете, как их использовать, вы должны учиться. Взгляните here

+0

или просто «(foldl + 0 (map sum-list * el))» – uselpa

+0

, но это работает только на один уровень вниз - попробуйте с помощью ((1) (2 3) (4) (5 6 (7 8 (9)))) как в моем ответе – uselpa

+0

Да, он работает только на один уровень вниз. Ваш код охватывает вложенный список. Я не знаю, хочет ли Лейла один или несколько уровней вниз (он написал «встроенные» списки и этот пример), но я только указывал на возможность использования некоторых важных функций списка, которые могут сделать код более кратким. Однако спасибо за ваше разъяснение. – Modestino

0

Вот простейший ответ.

(define (sum list-of-lists) 
    (apply + (apply append list-of-lists))) 

и «доказательства»:

> (sum '((1) (2 3) (4) (5 6))) 
21