Multiplying Elements in a List Containing Pairs

好久不见. 提交于 2019-12-11 22:40:00

问题


I'm trying to write a code (function) using Scheme that:

  • Takes a list of any size as a parameter
  • Multiplies every number of the list together
  • Symbols should be skipped over
  • Values inside pairs should be included in multiplication

In other words, results should be as follows:

> (mult '(1 2 3))
6
> (mult '(1 2 x 3 4))
24
> (mult '(1 2 z (3 y 4)))
24 (mine gives me 2)

My code allows me to skip over the symbols and multiply everything. However, once I include a pair inside the list, it acts as though it isn't a number, therefore acting like it doesn't exist. Here's my code:

(define mult
       (lambda (x)
               (if (null? x)
                      1
                      (if(number? (car x))
                         (* (car x) (mult (cdr x)))
                         (mult(cdr x))))))

I've tried to use append when it finds a pair, but clearly I did it wrong... Any help on how I could get it to include the values inside a pair would be much appreciated.

i.e. '(1 2 y (3 z 4) = 1 * 2 * 3 * 4


回答1:


You are nearly there, just missing the list? test:

(define (mult lst)
  (if (null? lst) 
      1
      (let ((ca (car lst)))
        (cond
          ((number? ca) (* ca (mult (cdr lst))))
          ((list? ca)   (* (mult ca) (mult (cdr lst))))
          (else         (mult (cdr lst)))))))

EDIT

He're an equivalent version without let:

(define (mult lst)
  (cond
    ((null? lst)         1)
    ((number? (car lst)) (* (car lst) (mult (cdr lst))))
    ((cons? (car lst))   (* (mult (car lst)) (mult (cdr lst))))
    (else                (mult (cdr lst)))))

As you see, (car lst) is likely to be evaluated more than once, so I used let in the first version to avoid this.




回答2:


It is a slightly advanced technique but this problem can easily be formulated as a tail recursive algorithm.

(define (mult lst)
  (let multiplying ((lst lst) (r 1))   ; r is the multiplicative identity...
    (if (null? lst)
        r
        (let ((next (car lst))
              (rest (cdr lst)))
          (multiplying rest (cond ((number? next) (* next r))
                                  ((list?   next) (* (mult next) r))
                                  (else           r)))))))
> (mult '(1 2 3 a b (((((10)))))))
60

Using tail recursion has performance implications but, admittedly, it is not the first thing to learn - recursion is. However, in this case, because lists are often very long, avoiding a stack frame for each list element can be a dramatic savings; using tail calls avoids the stack frame.



来源:https://stackoverflow.com/questions/18937637/multiplying-elements-in-a-list-containing-pairs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!