方案递归通过参数

时间:2015-02-11 23:52:44

标签: recursion scheme

我是Scheme的新手,这是一个家庭作业问题,所以请不要直截了当地回答。

这是我的问题:

  

写一个递归过程(任何?arg1 arg2 ...),其中argi是   布尔值。任何?如果它的任何参数是#t和#f,则返回#t   否则。

这些是限制因素:

  

您不能使用内置程序map,apply,list-> vector或   任何程序中的vector->列表。同样,不要使用let表达式   或者在任何过程中使用内部定义表达式,除非出现问题   另有说法。

这是我的代码:::

(define any?
  (lambda args
    (if (null? args)
        #f
        (if (equal? #t (car args))
            #t
            (any? (cdr args))))))

我的问题似乎是我在最后一行上遇到无限循环(任何?(cdr args))。我不确定为什么会这样。我的教授说要暗示要写任何一个?作为接口过程,并编写一个处理列表的帮助器。我不确定这会有什么帮助。

任何建议都将不胜感激!

编辑:我添加了新代码。我仍然无限循环。

(define any?
  (lambda args
    (any-helper args)))

(define any-helper
  (lambda (list)
    (if (null? list)
        #f
        (if (equal? #t (car list))
            #t
            (any? (cdr list))))))

我想通过在我的main函数中编写lambda args,我会将一个列表传递给我的辅助函数。我不确定这是否真的发生了。我不确定如何确保我不会无限地推翻(#)。

2 个答案:

答案 0 :(得分:1)

考虑函数应用程序(any? #f)采取的步骤。这会导致对(any? '())的递归调用。接下来,它会检查此调用中的参数列表'(())是否为null?(它不是,因为它是包含'()的列表)。 (equal #t '(())也是假的,所以它会一直递归,因为你用相同数量的参数调用它而不是减少每次递归调用中输入的大小。

嘿,这是我的第100个答案!

答案 1 :(得分:1)

当您将符号参数或点列表作为原型时,最后一个参数(在您的情况下为args)包含其余的给定操作数。

想象一下,您评估(any? #f 5 6),然后args(#f 5 6)。由于第一个参数为#f,因此您拨打(any? '(5 6))而不是(any? 5 6)

通常你会创建一个名为let或一个本地过程来处理一个参数列表,这样你的代码实际上可以工作,但是因为你不允许你需要使用apply来做相反。

(apply any? '(#f 5 6))(any? #f 5 6)相同。您可以将apply视为与过程定义中的虚线列表/符号原型相反的。

PS:如果您使用any-helper代替any-helper进行递归,那么使用any?的更新将非常有效。