4

So i have been stuck trying to learn this Scheme language that i heard about from a friend of mines. What he said i should do is start small and work my way up to truly understanding it. So after reading a textbook that he had that discusses Scheme programming briefly, i am a little puzzled myself on how it works.

So pretty much what i am trying to ask is that if i wanted to add a definition to a function called, let's say 'evens' from a couple of list i have define:

(DEFINE list0 (LIST 'j 'k 'l 'm 'n 'o 'j) )
(DEFINE list1 (LIST 'a 'b 'c 'd 'e 'f 'g) )
(DEFINE list2 (LIST 's 't 'u 'v 'w 'x 'y 'z) )
(DEFINE list3 (LIST 'j 'k 'l 'm 'l 'k 'j) )
(DEFINE list4 (LIST 'n 'o 'p 'q 'q 'p 'o 'n) )
(DEFINE list5 '((a b) c (d e d) c (a b) )
(DEFINE list6 '((h i) (j k) l (m n)) )
(DEFINE list7 (f (a b) c (d e d) (b a) f) )

such that it does like the task below: evens

which I have already created a adder function which i believe is to be:

(DEFINE (adder lis)
    (COND
        ((NULL? lis) 0)
        (ELSE (+ (CAR lis) (adder (CDR lis))))
))

what might the definition for even be if i would want it to do like the task below:

EVENS: (evens 1st) should return a new list, formed from the the even numbered elements taken 1st.

(evens '(a b c d e f g))
which would/should return:
(b d f)

and:

(evens (LIST 's 't 'u 'v 'w 'x 'y 'z))
which would/should return:
(t v x z)

and:

(evens '(f (a b) c (d e d) (b a) f) )
which would return:
((a b) (d e d) f)

and both (evens '()) and (evens '(a))

would return the empty list.

I have been going through trail in error to practice but i am totally lost. Thanks in advance

Okay, I think that i have come up with a recursive function to my example that i have been trying to work out:

 (define mylist '(1 2 3 4 5 6 7))
 (define (evens lst)
 (define (do-evens lst odd)
     (if (null? lst)
 lst
     (if odd
         (do-evens (cdr lst) #f)
         (cons (car lst) (do-evens (cdr lst) #t)))))
         (do-evens lst #t))

any thoughts?

4

3 回答 3

2

首先,adder功能与您的问题无关,对吗?

想想evens功能。您已经说过,(evens '())应该(evens '(a))返回空列表。应该(evens '(a b))返回什么?怎么样(evens '(a b ...))?你知道如何设置递归吗?

于 2012-11-09T22:34:03.797 回答
2

好的,所以要做一个遍历列表的递归函数,选择一些元素返回而不是其他元素,基本模式将是

(define (recur l)
  (cond
    ((null l) '())
    ((??????) (cons (car l) (recur (cdr l))))
    (else (recur (cdr l)))))

那是什么

  1. 列表是否为空?返回空值。
  2. 如果列表不为空,我们是否应该保留列表中的第一项?好的,让我们保留它并将其添加到任何(recur (cdr l))返回
  3. 否则,只返回任何recur (cdr l)返回。

我希望这清楚的是,一个简单的递归列表函数只查看列表的第一个元素,确定如何处理它,然后用列表的其余部分再次调用自己。从某种意义上说,递归是一种简化计算的方法,它只处理数据的第一部分,让另一个函数来处理其余数据(另一个函数实际上与您第一次调用的函数相同,但是尽量不要担心)。例如,仅返回偶数项的递归函数可能如下所示:

(define (even-numbers l)
  (cond
    ((null? l) '())
    ((even? (car l)) (cons (car l) (even-numbers (cdr l))))
    (else (even-numbers (cdr l)))))

也就是说,您的情况稍微复杂一些;您需要删除第一个元素,然后在每次连续调用该函数时,执行与上次调用相反的操作。

一种方法是传递一个布尔状态,每次都翻转它。请注意,由于events函数不获取状态,因此您必须定义一个不同的内部函数并在其上重复:

(define (evens l)
  (let loop ((lst l) (keep #f))
      (cond
         ((null? lst) '())
         ((eq? keep #t) (???????)
         (else (loop (cdr l) #t)))))

(???????)鉴于前面的示例,您应该能够弄清楚自己需要做什么。我想,我为你做了太多的工作。

另一种方法是使用相互递归的函数evensodds。考虑到

  1. evens是一个函数,它丢弃第一个元素,然后遍历列表,每次都执行与上次相反的操作(保留或丢弃)。
  2. 几率是一个函数,它保留第一个元素,然后遍历列表,每次都与上次相反(保留或丢弃)。

这意味着您可以定义

  1. evens作为一个忽略第一个元素并简单地调用列表其余部分的奇数的函数。
  2. 赔率作为保留第一个元素的函数,在列表的其余部分调用evens并将第一个元素cons -es 到结果的开头。

那看起来像

(define (evens l)
  (cond
    ((null? l) '())
    (else (odds (??????)))))

(define (odds l)
  (cond
    ((null? l) '())
    (else (cons (car l) (evens (??????))))))

希望这是有道理的。

如果您真的想了解 Scheme 中的递归,请购买一本《The Little Schemer》并开始学习。

于 2012-11-11T06:45:29.337 回答
0

那这个呢:

(define (evens l)
  (cond
   ((null? l) '())
   ((null? (cdr l)) '())
   (else (cons (cadr l) (evens (cddr l))))))

但我喜欢偶数和赔率的答案!

于 2014-07-17T12:43:57.657 回答