在Scheme中创建非常大的列表
我随身携带物品清单。这些对象称为字对 例如:在Scheme中创建非常大的列表,scheme,Scheme,我随身携带物品清单。这些对象称为字对 例如:((WordPair1)(WordPair2))等等。我有一个函数提取它们的置信值。我想用它们的置信值创建另一个列表。该列表将只有数字。在这个计算结束时,我将得到一个与单词对列表相对应的数字列表。我知道如何使用cons创建基本列表。这里的问题是,我有500000个字对,使用递归cons,我会很快遇到堆栈溢出 解决办法是什么 我天真的解决方案是: (define (create-conf-list lst) (define wp (car lst)) (
((WordPair1)(WordPair2))
等等。我有一个函数提取它们的置信值。我想用它们的置信值创建另一个列表。该列表将只有数字。在这个计算结束时,我将得到一个与单词对列表相对应的数字列表。我知道如何使用cons
创建基本列表。这里的问题是,我有500000个字对,使用递归cons,我会很快遇到堆栈溢出
解决办法是什么
我天真的解决方案是:
(define (create-conf-list lst)
(define wp (car lst))
(define confidence (tv-conf (cog-tv wp)))
(if (not (null? (cdr lst)))
(cons confidence (create-conf-list (cdr lst)))
'()))
如何改进这一点
附言:我用这种方法遇到了堆栈溢出。我需要一个更有效的方法。我想不出如何在这里插入尾部递归。这看起来像是你可以用“累加和反转”来做的,因为你希望结果与直接累加产生的结果相反:
(define (helper ls acc)
(define wp (car ls))
(define confidence (tv-conf (cog-tv wp)))
(if (null? (cdr ls))
(reverse acc)
(helper (cdr ls) (cons confidence acc))))
这是尾部递归,因为递归案例只是对函数本身的调用-递归调用的结果不用于任何其他内容。需要反转,因为累加器中的
cons
以相反的顺序构建列表。(您可能会尝试使用
(append acc(list confidence))
将列表保持在所需的顺序,但是append
使其速度非常慢。)
然后您可以从“实际”函数调用它:
(define (create-conf-list lst)
(helper lst '()))
或者,您可以将这些函数合并为一个:
(define (create-conf-list lst)
(define (helper ls acc)
(define wp (car ls))
(define confidence (tv-conf (cog-tv wp)))
(if (null? (cdr ls))
(reverse acc)
(helper (cdr ls) (cons confidence acc))))
(helper lst '()))
旁注:你放弃了自信的最后一个要素,但由于你正处于优化阶段,我想这就是你想要的。
如果它不是您想要的,您应该在考虑优化之前修复该错误。通过函数将列表映射到相应的值列表通常使用map完成
(define (get-confidence-values list-of-word-pairs)
(map (lambda (wp) (tv-conf (cog-tv wp)))
list-of-word-pairs))
很抱歉我的意思是检查列表是否为null,而不是
(cdrlst)
,这尾递归是如何实现的?你能解释一下密码吗?我想不出这里面的尾部递归,明白了!非常感谢。积累到底是什么?“你能给我指出一些解释累加的资源吗?”RohitShinde在讨论尾部递归时,有任何关于函数编程的书,特别是Scheme。如果你有“SICP”——计算机程序的结构和解释()——请阅读有关迭代过程的章节。如何设计程序(“HtDP”)也很重要。似乎表明您的方法更快(可能是因为map
是内置的)。@WillNess 500000个实体如果堆栈帧较大,可能会导致堆栈分配问题。另一方面,如果每个对象的大小为1000字节,那么仍然只有半GB的分配空间(或者少于1.00美元的RAM)<代码>映射是这样一种地方,在这种地方,为了实现而下拉到C中,为了性能而在内部使用变异可能是合理的。@这就是为什么使用映射
是“通常完成的”。关于“大”的另一个问题只是需要时间来了解它对算法效率的依赖性。如果算法有O(30!),那么30是很多,而现在如果算法是O(n),那么200万算不了什么,就像处理列表操作时一样。为了方便起见,可以使用结构变异以自顶向下的方式迭代构建列表。