Fre*_*d_2 2 lisp iteration recursion common-lisp
我使用循环函数在LISP中写下了这个迭代代码:
(defun loadfile (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil 'eof)
until (eq line 'eof)
collect line)))
)
)
Run Code Online (Sandbox Code Playgroud)
有没有办法以loop递归的方式重写它?
用GOTO给他们惊喜:
(defun loadfile (filename)
(with-open-file (stream filename)
(prog (line lines)
repeat
(setf line (read-line stream nil))
(when line
(push line lines)
(go repeat))
(return (reverse lines)))))
Run Code Online (Sandbox Code Playgroud)
当然,任何循环都可以在递归中进行转换,但是在一段时间内读取整个文件是一个典型的迭代过程,因此我发现这个问题很难激发.
这是一个可能的递归版本,其中递归由内部函数管理:
(defun load-file (filename)
(with-open-file (stream filename)
(labels ((read-recursively ()
(let ((line (read-line stream nil 'eof)))
(if (eq line 'eof)
nil
(cons line (read-recursively))))))
(read-recursively))))
Run Code Online (Sandbox Code Playgroud)
如果文件的行数很大,则此解决方案容易出现堆栈溢出错误.
如果一个人有能够执行尾优化编译器,以下替代递归溶液可以在迭代的方式被编译并能避免堆栈溢出:
(defun load-file (filename)
(with-open-file (stream filename)
(labels ((read-recursively (read-so-far)
(let ((line (read-line stream nil 'eof)))
(if (eq line 'eof)
(reverse read-so-far)
(read-recursively (cons line read-so-far))))))
(read-recursively ()))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
212 次 |
| 最近记录: |