【发布时间】:2011-07-26 12:12:19
【问题描述】:
给定一个字母表["a"; "b"; "c"] 我想将所有长度为 25 的序列转储到一个文件中。 (字母可以按顺序重复;这不是排列。)问题是,当我尝试使用以下代码时,我得到了 Stack overflow during evaluation (looping recursion?):
let addAlphabetToPrefix alphabet prefix =
List.map (function letter -> (prefix ^ letter)) alphabet;;
let rec generateWords alphabet counter words =
if counter > 25 then
words
else
let newWords = List.flatten(List.map (function word -> addAlphabetToPrefix alphabet word) words) in
generateWords alphabet (counter + 1) newWords;;
generateWords ["a"; "b"; "c"] 0 [""];; (* Produces a stack overflow. *)
有没有更好的方法来做到这一点?我正在考虑先生成整个列表,然后将整个列表转储到文件中,但是我是否必须重复生成部分列表然后转储?做一些懒惰的事情会有帮助吗?
究竟为什么会发生堆栈溢出? AFAICT,我的 generateWords 函数是尾递归的。我生成的words 列表是否太大而无法放入内存?
【问题讨论】:
-
ocaml 是否优化尾递归?
-
@Jeff:有趣!真的,我不知道 ocaml 是关于什么的。就是这样,我知道的语言似乎并不费心尝试优化尾递归:-)
-
你应该
#tracegenerateWords函数来看看它是否对这个主题有所启发。我认为这只是你在这里生成了一个巨大的列表(可能是 26^25 个单词),所以你自然会用完内存。加上你是递归生成这个,会有很多中间结果。
标签: ocaml stack-overflow tail-recursion