Scheme 我将如何着手提高效率(方案)?
我有以下代码:Scheme 我将如何着手提高效率(方案)?,scheme,Scheme,我有以下代码: (define tree `(A (B (C)) (D (E)) (C (E)))) (define (prog1 graph) (let ([seen `()]) (define (sub g) (cond [(member (car g) seen) `()] [else (set! seen (cons (car g) seen))
(define tree `(A (B (C)) (D (E)) (C (E))))
(define (prog1 graph)
(let ([seen `()])
(define (sub g)
(cond
[(member (car g) seen) `()]
[else
(set! seen (cons (car g) seen))
(cond
[(null? (cdr g)) (list (car g))]
[else
(cons (car g) (map sub (cdr g)))])]))
(delete `() (sub graph))))
(define delete
(lambda (x y)
(if (null? y )
`()
(if (eqv? (car y) x)
(delete x (cdr y))
(cons (car y) (delete x (cdr y)))))))
它打印一个连接图,其中所有节点显示一次
正在运行(程序树)
打印:(A(B(C))(D(E))
我已经研究了lisp中的各种深度优先搜索(类似于我正在尝试做的事情),它们看起来更加优雅,有些使用迭代方法。我知道这个程序效率不高(在大树上它运行得很慢),那么我该如何提高代码的效率呢
谢谢,James在大多数情况下,这段代码中的瓶颈不是树遍历,而是成员查找。函数的复杂度大约为O(M*N),其中M是不同节点的数量,N是总节点的数量。之所以将M作为一个因子,是因为您在线性列表中查找节点,这需要与列表长度成比例的时间(在您的情况下,它与不同节点的数量成比例)
摆脱M的方法是使用更高效的数据结构进行查找。例如,R6RS定义哈希表。成员过程每次调用时都对列表执行
O(n)
查找。这不是快速测试集合成员资格所需要的,因为您应该使用一个数据结构,为在集合中添加元素和测试元素成员资格提供O(1)
复杂性,最好是一个集合数据结构或一个哈希表。例如,在Racket中尝试替换这些行(或在方案解释器中使用默认哈希表实现):
另外,通常您希望在代码中使用:'()
而不是:`()
,请参阅链接以了解差异以及何时适合使用准量化
最后,您可以使用内置的
remove
过程,无需实现您自己的delete
您确定此功能完全满足您的需要吗?例如,(prog1’((a))给出((a))节点是唯一的,并且图形不能有循环。所以(a)不是一个有效的图
(let ([seen `()]) => (let ([seen (make-hash)])
[(member (car g) seen) `()] => [(hash-has-key? seen (car g)) '()]
(set! seen (cons (car g) seen)) => (hash-set! seen (car g) 'ok)