在 Scheme 中创建一个非常大的列表
Creating a very large list in Scheme
我有物品清单。这些对象称为 WordPairs。
例如:((WordPair1) (WordPair2))
等等。我有一个函数提取他们的置信度值。我想用他们的信心值创建另一个列表。该列表将只有数字。在此计算结束时,我将得到一个与 WordPairs 列表相对应的数字列表。我知道如何使用 cons
创建基本列表。这里的问题是我有 500,000 个单词对并且使用递归缺点我会 运行 很快进入堆栈溢出。
有什么解决办法?
我天真的解决方案是这样的:
(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)))
'()))
如何改进?
P.S:我运行使用这种方法陷入 Stack Overflow。我需要一种更有效的方法。我想不出如何在这里插入尾递归。
这看起来像您可以用 "accumulate and reverse" 做的事情,因为您希望结果的顺序与直接累加的顺序相反:
(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
会使它变得非常慢。)
然后你可以从"actual"函数中调用它:
(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 '()))
旁注:
您正在放弃置信度的最后一个元素,但由于您处于优化阶段,我认为这就是您想要的。
如果这不是你想要的,你应该在考虑优化之前修复那个错误。
通过函数将列表映射到相应的值列表通常使用映射来完成。
(define (get-confidence-values list-of-word-pairs)
(map (lambda (wp) (tv-conf (cog-tv wp)))
list-of-word-pairs))
我有物品清单。这些对象称为 WordPairs。
例如:((WordPair1) (WordPair2))
等等。我有一个函数提取他们的置信度值。我想用他们的信心值创建另一个列表。该列表将只有数字。在此计算结束时,我将得到一个与 WordPairs 列表相对应的数字列表。我知道如何使用 cons
创建基本列表。这里的问题是我有 500,000 个单词对并且使用递归缺点我会 运行 很快进入堆栈溢出。
有什么解决办法?
我天真的解决方案是这样的:
(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)))
'()))
如何改进?
P.S:我运行使用这种方法陷入 Stack Overflow。我需要一种更有效的方法。我想不出如何在这里插入尾递归。
这看起来像您可以用 "accumulate and reverse" 做的事情,因为您希望结果的顺序与直接累加的顺序相反:
(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
会使它变得非常慢。)
然后你可以从"actual"函数中调用它:
(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 '()))
旁注:
您正在放弃置信度的最后一个元素,但由于您处于优化阶段,我认为这就是您想要的。
如果这不是你想要的,你应该在考虑优化之前修复那个错误。
通过函数将列表映射到相应的值列表通常使用映射来完成。
(define (get-confidence-values list-of-word-pairs)
(map (lambda (wp) (tv-conf (cog-tv wp)))
list-of-word-pairs))