我有一个霍夫曼树和一个角色,我想要返回该角色在霍夫曼树中的编码应该是什么。
我使用广度优先遍历方法实现了它,每次我检查左右树时,我都在检查树的数据是否等于我正在寻找的字符。但是,每次我向右或向左移动时,我都会向编码添加0或1。最终,当我发现字符等于树的数据时,我返回该树的编码值。
代码:
public static String findCharEncoding(BinaryTree<CharProfile> bTree, char character) {
Queue<BinaryTree<CharProfile>> treeQueue = new LinkedList<BinaryTree<CharProfile>>();
// Create a TreeWithEncoding object from the given arguments and add it to the queue
treeQueue.add(bTree);
while (!treeQueue.isEmpty()) {
BinaryTree<CharProfile> t = treeQueue.remove();
-> if (t.getLeft().getData().getCharacter() == character) {
return t.getLeft().getData().getEncoding();
}
if (t.getLeft() != null) {
t.getLeft().getData().setEncoding(t.getLeft().getData().getEncoding() + "0");
treeQueue.add(t.getLeft());
}
if (t.getRight().getData().getCharacter() == character) {
return t.getRight().getData().getEncoding();
}
if (t.getRight() != null) {
t.getRight().getData().setEncoding(t.getRight().getData().getEncoding() + "1");
treeQueue.add(t.getRight());
}
}
// If it gets to here, the while loop was unsuccessful in finding the encoding
System.out.println("Unable to find.");
return "-1";
}
我实施的内容如下:
for (int i = 0; i < charOccurrences.size(); i++) {
char character = charOccurrences.get(i).getCharacter();
charOccurrences.get(i).setEncoding(findCharEncoding(huffmanTree, character));
System.out.println(charOccurrences.get(i).getEncoding());
}
CharProfile是一个自定义类,用于保存字符值,字符的概率和编码。
它在if (t.getLeft().getData().getCharacter() == character) {
行继续返回NullPointerExceptionError,我用箭头表示。我已经尝试过,但我似乎无法弄明白为什么。
答案 0 :(得分:1)
t
null
或t.getLeft()
返回null
或t.getLeft().getData()
返回null
。
由于我们只看到您显示的代码,因此调试它是您的工作。
您可以在错误上方插入一行:
if (t == null) {
System.out.println("t = null");
} else if (t.getLeft() == null) {
System.out.println("t.getLeft() returns null");
} else if (t.getLeft().getData() == null) {
System.out.println("t.getLeft().getData() returns null");
}
答案 1 :(得分:0)
正如评论中所指出的,您正在检查t.getLeft()
是否一度返回null
而不是其他点。另外,就个人而言,我只是讨厌一直反复调用相同方法的代码。我可能会参考这一部分:
if (t.getLeft().getData().getCharacter() == character) {
return t.getLeft().getData().getEncoding();
}
if (t.getLeft() != null) {
t.getLeft().getData().setEncoding(t.getLeft().getData().getEncoding() + "0");
treeQueue.add(t.getLeft());
}
并将其重写为:
left = t.getLeft();
if ( left != null ) {
data = t.getData();
encoding = data.getEncoding();
if ( data.getCharacter() == character ) {
return encoding;
else {
data.setEncoding( encoding + "0" );
treeQueue.add( left )
}
}
(我已经为我添加的变量省略了类型声明,因为我不确定正确的类型名称。)
如果NullPointerException
正在返回t.getLeft()
,则应该避免null
;否则,当异常发生时,你至少应该更清楚地看到哪个引用是null
,因为你不会在一行中有多个解引用。右侧的部分可以用相同的方式重写(实际上看起来你可以制作一个简单地传递左右值的方法,因为你对两者都做同样的事情。)