在Scheme

时间:2015-05-19 04:01:28

标签: 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。我需要一种更有效的方法。我想不出如何在这里插入尾递归。

2 个答案:

答案 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))