我的整个项目是创建一个树并使用霍夫曼编码对给定文件进行编码和解码。我正处于需要解码文件的位置。要做到这一点,我必须穿过我的霍夫曼树,直到我到达最底部的叶子,然后返回由该叶子代表的字节。我根据给出方法的位串遍历树。 AKA如果当前位为1,我会在树中转到childOne,依此类推。问题是我不断收到outOfMemory
错误。有没有办法优化这段代码,以便它不会使用尽可能多的内存?
public static int decode(List<Integer> bitArray, HuffmanNode root, int startingPosition,
ArrayList<Byte> finalArray)
{
HuffmanNode childOne;
HuffmanNode childZero;
int currentBit = bitArray.get(startPosition);
byte newByte;
childOne = root.getChildOne();
childZero = root.getChildZero();
if(childOne == null && childZero == null)
{
finalArray.add(root.getByteRepresented());
return startPosition;
}
else if(currentBit == 1)
{
startPosition++;
startPosition = decode(bitArray,childOne,startPosition,finalArray);
}
else
{
startPosition++;
startPosition = decode(bitArray,childZero,startPosition,finalArray);
}
return startPosition;
}
我需要知道bitArray中它结束的位置以及将指定的Byte放入数组中,这就是为什么我将Byte放入方法中的数组并返回和int。基本上,有没有更好的方法来完成这项工作?
答案 0 :(得分:2)
是的,有。将递归更改为迭代..
temp = root;
childOne = temp.getChildOne();
childZero = temp.getChildZero();
while(childOne != null && childZero != null) {
currentBit = bitArray.get(startPosition++);
if (currentBit == 1) {
temp = childOne;
} else {
temp = childZero;
}
childOne = temp.getChildOne();
childZero = temp.getChildZero();
}
答案 1 :(得分:0)
我不知道有多大的东西,但我认为你不需要递归。你不能用这样的循环做你需要的东西:
while (curNode.isNotLeaf())
{
if (currentBit == 1) curNode = curNode.getChildOne();
else curNode = curNode.getChildZero();
currentBit = nextBit;
}
addByte(curNode, bigArray)
所以你在这个循环中查看你的位,在你离开时添加表示的字节,然后继续 - 不需要所有的堆栈帧递归涉及。
答案 2 :(得分:0)
此外,请考虑使用较低级别的数据结构,例如java.util.BitSet
而不是List<Integer>
和java.io.ByteArrayOutputStream
,而不是ArrayList<Byte>
。
答案 3 :(得分:0)
如果递归是您的问题,您很可能会遇到堆栈溢出错误。当你的内存不足时,我建议你看看:
bitArray
和finalArray
。BitSet
作为bitArray。答案 4 :(得分:-1)
看看压缩位设置实现如何 OpenBitSet(Lucene) http://code.google.com/p/javaewah/ http://www.censhare.com/en/aktuelles/censhare-labs/yet-another-compressed-bitset