我有对象列表。这些对象称为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。我需要一种更有效的方法。我想不出如何在这里插入尾递归。
答案 0 :(得分:1)
这看起来像你可以做的事情"累积和反转",因为你想要的结果与直接累积产生的顺序相反:
(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 '()))
旁注:
你放弃了信心的最后一个要素,但是既然你已经处于优化阶段,我认为这就是你想要的。
如果它不是您想要的,那么您应该在考虑优化之前修复该错误。
答案 1 :(得分:1)
通过函数将列表映射到相应的值列表通常使用map来完成。
(define (get-confidence-values list-of-word-pairs)
(map (lambda (wp) (tv-conf (cog-tv wp)))
list-of-word-pairs))