我刚刚使用Scala实现了Huffman代码。但是,我的一个功能在大文件上运行不佳。这是解码函数,我使用过多的递归:
import axios from "axios";
var customData = require('./db.json');
export function fetchUsers(){
return function(dispatch){
axios.get('./db.json')
.then((response) => {
dispatch({type:'FETCH_USERS_FULFILLED', payload:response.data});
})
.catch((err) => {
dispatch({type:'FETCH_USERS_REJECTED', payload:err});
})
}
}
当我有一个小位列表时,它很好,但是当我的位列表很大(超过10000项)时,它会给出StackOverflow错误。我只是找不到我可以使用更少的递归来优化它的地方。我知道问题在于叶子中的递归调用(而不是fork)。
如何删除此递归调用但仍保持功能正常?
答案 0 :(得分:3)
乍一看,您的实现在.tail
分支中缺少LeafNode
,因此每当您点击Leaf
节点时,您只是一遍又一遍地调用相同的函数,因为bits
并没有缩小。
其次,你可以使递归函数为tail-recursive,这样它的堆栈是安全的:
def decode(tree: BinarySearchTree, bits: List[Boolean]): List[Char] = {
@scala.annotation.tailrec
def searchCharactersInBinarySearchTree(t: BinarySearchTree, b: List[Boolean], acc: List[Char] = Nil): List[Char] = t match {
case LeafNode(ch, _) => if (b.isEmpty) acc else searchCharactersInBinarySearchTree(tree, b.tail, ch :: acc)
case ForkNode(l, r, _, _) => if (b.head == false) searchCharactersInBinarySearchTree(l, b.tail) else searchCharactersInBinarySearchTree(r, b.tail)
}
searchCharactersInBinarySearchTree(tree, bits)
}
请注意,tailrec
注释除了使编译器检查该方法实际上是尾递归之外没有做任何事情。