一个函数,它将确定传入列表是否遵循A B模式

时间:2013-10-16 00:43:31

标签: list scheme racket lambda

(define fun4

 (lambda ( ls)

(cond ((null? ls ) #f)

 (cons (((eqv? 'a (car ls))) && ((eqv? 'b (cdr ls)))))

(else (pattern2 cdr ls)))))

在此显示错误 - 程序应用程序:预期程序,给定:#t(无参数), 我的代码中的错误是什么?逻辑是否正常?

3 个答案:

答案 0 :(得分:2)

您的解决方案中存在许多错误。让我们看看每个条件都有什么问题:

  1. 递归(空列表)的基本情况是错误的:空列表是递归的退出,这意味着列表已正确遍历并且遵循模式
  2. 缺少另一个基本案例:如果列表包含单个元素该怎么办?
  3. 如果模式不成立,我们必须立即返回#f,并注意我们如何使用cadr来访问第二个元素,因为&&在Scheme中不起作用,您必须使用and进行逻辑操作。此外,每个测试都有不必要的,错误的括号(顺便说一句:那些导致“预期程序”错误的那些)
  4. 只有当上述条件都不成立时我们才会推进递归,我们通过使用cddr两个元素向下移动到列表中来实现。此外,您必须致电fun4以推进递归,而不是pattern2
  5. 这是解决问题的正确方法,请注意上述问题是如何解决的:

    (define fun4
      (lambda (ls)
        (cond ((null? ls) #t)                                       ; 1
              ((null? (cdr ls)) #f)                                 ; 2
              ((not (and (eq? 'a (car ls)) (eq? 'b (cadr ls)))) #f) ; 3
              (else (fun4 (cddr ls))))))                            ; 4
    

    始终测试您的程序,以上将正常工作:

    (fun4 '())
    => #t
    (fun4 '(a))
    => #f
    (fun4 '(a b))
    => #t
    (fun4 '(a b a))
    => #f
    (fun4 '(a b a b))
    => #t
    

    作为最后一点,如果空列表不应该遵循该模式,那么在调用fun4之前检查它,如果初始输入列表为空,则返回#f

答案 1 :(得分:0)

(define fun 
  (lambda (ls)
    (cond ((null? ls) #t)
          ((and (eq? (car ls) 'a)       ; the first item is a
                (list? (cdr ls))        ; the rest of the list
                (not (null? (cdr ls)))  ; which is not null
                (eq? (cadr ls) 'b)      ; and it starts with b
                (fun (cddr ls))) #t)    ; and the rest of the expression is 
          (else #f))))                  ; also in the A B format

运行:

> (fun '(a b a b))
#t
> (fun '(a b a))
#f
> (fun '(a b))
#t
> (fun '(a))
#f
> (fun '())
#t
> 

答案 2 :(得分:0)

如此多的车轮改造。只需使用SRFI 1!

(require srfi/1)
(define (fun4 lst)
  (every eq? lst (circular-list 'a 'b)))

(这假设(a b a)应该有效而不是无效。)