简体   繁体   中英

Decoding a message with Huffman tree

When I send a string of bits to be decoded, it seems to require one additional bit to decode properly. I've printed out the tree in pre-order, and I've drawn the tree on paper to make sure I wasn't missing something. The pre-order and my drawn tree match, but the bits required to produce the correct letter is off.

public void decode(String code){
    String result = "";
    TreeNode current = root;
    current.preOrder();
    for(int i = 0;i < code.length();i++){
        //left--0
        if(Character.getNumericValue(code.charAt(i))==0){
            if(current.getLeft() == null){
                result += current.getWeight().getLetter();
                current = root;
                i--;
            }else
                current=current.getLeft();
        }
        //right--1
        else if(Character.getNumericValue(code.charAt(i))==1){
            if(current.getRight() == null){
                result += current.getWeight().getLetter();
                current = root;
                i--;
            }else
                current=current.getRight();
        }
    }
    System.out.println(result);
}

My tree is building correctly every time which makes me believe the error is in the decoding method. However, I can't seem to figure out why it needs additional bits.

Without seeing how your nodes are laid out I can only guess. When traversing left/right you probably need to check if you've landed on a leaf node and emit its character if so.

if (current.getLeft() == null) {
    ...
}
else {
    current = current.getLeft();
    if (current.isLeaf()) {
        result += current.getWeight().getLetter();
        current = root;
    }
}

The same goes for the right side.

Don't Repeat Yourself

To avoid duplicating the two lines that append the character and reset the current node to the root four times, you could instead set a flag and check it at the end of the for block.

boolean append = false;
if (Character.getNumericValue(code.charAt(i)) == 0) {
    if (current.getLeft() == null) {
        append = true;
        i--;
    }
    else {
        current = current.getLeft();
        if (current.isLeaf()) {
            append = true;
        }
    }
}
// same for right side ...
if (append) {
    result += current.getWeight().getLetter();
    current = root;
}

Other Tips

  • Switch from two if checks for 0 or 1 to a switch with a default that throws an IllegalArgumentException .
  • Switch the for loop to a while to avoid pre-decrementing i just to have it incremented again and avoid stopping the loop.
  • Start with append set to true since four out of six cases append.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM