交替清单

时间:2013-03-10 16:53:18

标签: scheme

我需要创建一个函数来检测列表是否在原子和子列表之间交替。因此,例如,如果列表为(a(bc)d(ef)),则返回true;如果列表为(a b),则返回false

这是我到目前为止所做的:

(define (altlist? lis)
(cond
((null? lis)#t)
((null? (cdr lis))#t)
((list? (car lis))
 (not(list? (cadr lis)
            (altlist? cdr lis)
           '() )
     (list? (cadr lis)
            (altlist? cdr lis)
           '())
     ))))

3 个答案:

答案 0 :(得分:0)

函数list?not接受一个参数(请参阅http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-14.html#node_sec_11.1),并且您无法理解第三个cond子句的含义。

同时,解决方案更短:

(define (altlist? lis)
  (cond
   ((null? lis) #f)
   ((null? (cdr lis)) #f)
   ((not
     (eq? (list? (cadr lis))
          (list? (car lis))))
    #t)
   (#t (altlist? (cdr lis)))))

这个想法是一个接一个地检查给定列表的后续对。并且对于每个比较是否两者都是列表,或者两者都是原子。如果列表包含列表和原子,则会有一对(列表原子)或(原子列表),反之亦然。

编辑:

正如@molbdnilo指出的那样,原来的功能实际上试图检查列表是否不交替。

编辑:

现在我看到,交替列表不仅仅是一个包含列表和原子的列表,所以请看GoZoner解决方案。本实现仅检查给定列表中存在的原子和缺点。

答案 1 :(得分:0)

你走了:

(define (alt-list? l)
  (or (null? l)
      (and (not (null? (cdr  l)))
           (not (list? (car  l)))  ; atom
           (list? (cadr l))        ; list
           (alt-list? (cddr l)))))

具体代码取决于以下是否为“交替列表”:

  1. '(a(b c)d)
  2. '((a b)c)
  3. 我提供的代码需要(原子列表)* => #T

答案 2 :(得分:0)

这是你的代码,移动了一些括号,添加了一些注释和缩进(以使其可读),以及一些更正:

(define (altlist? lis)
  (cond
    ((null? lis) #t)                  ; end-of-list successfully reached
    ((null? (cdr lis)) #t)            ; ditto
    ((list? (car lis))                ; first elt is a list
      (and (not (list? (cadr lis)))   ; fixed: use AND
           (altlist? (cdr lis))))
    (else                             ; fixed: ELSE clause
      (and (list? (cadr lis))         ; fixed: use AND
           (altlist? (cdr lis))))))

所以你很亲密写下你的代码时要小心。

这里有一个微妙之处。 (list? '())返回true。如果您更喜欢将空列表视为原子而不是列表,那么您可以使用list?代替pair?而不是{{1}}。