【问题标题】:Recursion with more than one function具有多个函数的递归
【发布时间】:2016-08-17 20:36:33
【问题描述】:

你们中的一些人可能会觉得这个问题有点奇怪,但我真的很想知道这个程序是否是递归的,这就是我想知道的。

(defun howmany(sez)
  (if (null sez)
      0
    (+ 1 (howmany (cdr sez)))))

(defun sum(sez)
  (if (null sez)
      0
    (+ (car sez) (sum(cdr sez)))))

(defun avg(sez)
  (if (null sez)
      0
    (/ (sum sez) (howmany sez))))

(print (avg '(100 200 300)))

感谢您的所有回答!

【问题讨论】:

  • 几乎不可能阅读未格式化的 Lisp 代码。请缩进您的代码。例如,您的代码应该看起来像:pastebin.com/raw/ZdPp8A0i。使用问题下方的edit 链接。
  • 虽然你问的不是很清楚。 SUM 调用自己,HOWMANY 调用自己,所以它们都是递归的,当然。请注意,您可以只做(defun avg (seq) (/ (reduce '+ seq) (length seq))。无需重新实现 LENGTH 和列表求和函数。
  • 但是您正在使用内置函数:+、/、null、car、cdr(并且这些函数位于一些内置非函数之上:defun 和 if )。
  • 每一个最终调用它实现的函数名的函数都是递归的。您的所有功能都可以做到这一点。它们甚至是递归过程,因为它们会增加堆栈,而您可以通过使用累加器轻松完成所有这些迭代过程。您可能很快就会了解更多相关信息 :-) sez 是某种语言的列表吗?
  • 如果你自己都想不通,那你肯定不明白“递归”是什么意思。

标签: recursion common-lisp


【解决方案1】:

首先,看一下你的代码并对其进行更多格式化,以便 lisper 轻松阅读

(defun howmany (sez)
  (if (null sez)
      0
      (+ 1 (howmany (cdr sez)))))

(defun sum (sez)
  (if (null sez)
      0
      (+ (car sez) (sum (cdr sez)))))

(defun avg (sez)
  (if (null sez)
      0
      (/ (sum sez) (howmany sez))))

(print (avg '(100 200 300)))

然后分析这个脚本,它包含三个函数,最后一个 s 表达式对函数求值。

对于这三个函数,avg、sum和howmany,

有一个名为 Martin and the Dragon 的故事,你可以从这里Common Lisp: A Gentle Introduction to Symbolic Computation 找到第 8 章,你应该阅读,总结如下:

龙,在它对马丁的问题的假装厌恶之下, 实际上很喜欢教他递归。有一天它决定 正式解释递归的含义。龙告诉马丁 处理每一个递归问题,就好像它是一个旅程一样。如果他 遵循递归解决问题的三个规则,他总是 成功完成旅程。

龙是这样解释规则的:

  1. 知道何时停止。
  2. 决定如何迈出一步。
  3. 将旅程分解为那一步加上更小的旅程。

让我们看看函数howmany和sum

  1. 知道何时停止 它在 sez 为空时停止,即当列表为空时

  2. 决定如何迈出一步

if 有两种方式 or 两种方式都为 0 或

(+ 1 (howmany (cdr sez)))
(+ (car sez) (sum (cdr sez)))
  1. 将旅程分解为那一步加上更小的旅程

在最后一个表达式中,列表较小,取出第一个然后继续,列表较小

所以,这两个函数是递归的,另一个 avg 不是递归的,只处理空列表,以防止除以零或零/零不确定性。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 2021-04-19
    相关资源
    最近更新 更多