0

我需要创建一个函数来检测列表是否在原子和子列表之间交替。因此,例如,如果列表为 (a (bc) d (ef)),它将返回 true,如果列表为 (ab),则返回 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)
           '())
     ))))
4

3 回答 3

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? '())返回真。如果您更愿意将空列表视为原子,而不是列表,那么list?您可以使用pair?.

于 2013-03-11T13:53:57.063 回答
0

函数list?not接受单个参数(请参阅http://www.r6rs.org/final/html/r6rs/r6rs-ZH-14.html#node_sec_11.1cond ),您无法理解第三个子句是什么意思。

同时,解决方案甚至更短:

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

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

编辑:

正如@molbdnilo 所指出的,原始函数实际上试图检查列表是否不是交替的。

编辑:

现在我明白了,交替列表不仅仅是一个包含列表和原子的列表,所以看看 GoZoner 解决方案。目前的实现只检查给定列表中是否存在一个原子和一个缺点。

于 2013-03-10T17:15:15.373 回答
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. '((ab)c)

我提供的代码需要(原子列表)* => #t

于 2013-03-10T18:06:14.280 回答