-1

The snippet below is not returning the correct text. The code takes in a pointer to the root node of a Huffman code tree and a binary text, which it then converts. However, every time it returns a single letter repeated.

string decode(Node *root, string code) {
    string d = ""; char c; Node *node = root;
    for (int i = 0; i < code.size(); i++) {
        node = (code[i] == '0') ? node->left_child : node->right_child;
        if ((c = node->value) < 128) {
            d += c;
            node = root;
        }
    }
    return d;
}

The code for the Node object:

class Node {
public:
  Node(int i, Node *l = nullptr, Node *r = nullptr) {
      value = i;
      left_child = l;
      right_child = r;
  }
  int value;
  Node *left_child;
  Node *right_child;
};

The code for building the tree:

Node* buildTree(vector<int> in, vector<int> post, int in_left, int in_right, int *post_index) {
    Node *node = new Node(post[*post_index]);
    (*post_index)--;

    if (in_left == in_right) {
        return node;
    }

    int in_index;
    for (int i = in_left; i <= in_right; i++) {
        if (in[i] == node->value) {
            in_index = i;
            break;
        }
    }

    node->right_child = buildTree(in, post, in_index + 1, in_right, post_index);
    node->left_child = buildTree(in, post, in_left, in_index - 1, post_index);

    return node;
}

Example tree:

        130
       /   \
     129    65
    /   \
  66     128
        /   \
      76     77 

Example I/O: Input: 101010010111 Output: A�A�A��A�AAA

The diamond characters are the numbers greater than 128.

  • Any debugger usage on your part? – PaulMcKenzie Nov 24 '18 at 03:36
  • You'd be surprised to learn that "`code[i] == 0`" does ***not***, I repeat, does not check if the ith character in the `code` std::string is the character '0' a.k.a. ASCII code 48. – Sam Varshavchik Nov 24 '18 at 03:37
  • I like your `Node` class. You'd be surprised how many people don't bother to ensure the link pointers are nulled. – user4581301 Nov 24 '18 at 03:43
  • @Sam Varshavchik, sorry it should be '0'. It was caught that before I posted, but didn't edit it out. – Tyler West Nov 24 '18 at 03:47
  • @PaulMcKenzie, debugger outputs "[Inferior 1 (process 20521) exited normally]" – Tyler West Nov 24 '18 at 03:55
  • @TylerWest -- No, you did not use the debugger in the way that it is meant to be used. The debugger allows you to run your program step-by-step, one function / line at a time, allowing you to watch variables, observe the flow, set breakpoints, etc. What you did is simply run your program at full-speed with no debugging being done. – PaulMcKenzie Nov 24 '18 at 04:38
  • @PaulMcKenzie, in (gdb) I typed "r arg1 arg2 arg3" and that was the final output. Is that wrong? – Tyler West Nov 24 '18 at 05:48
  • So I guess you never used a debugger before. Didn't you step through the program one line at a time, or at least investigate how to do that? You really need to learn how to use a debugger -- it is a tool that every programmer has to learn to use, no exceptions. – PaulMcKenzie Nov 24 '18 at 06:22

1 Answers1

0

You are putting the value in a char, which for most C++ compilers is signed. But not all -- whether char is signed or unsigned is implementation defined. A signed char is in the range –128 to 127, so it is always less than 128. (Your compiler should have warned you about that.)

You need to use int c; instead of char c; in decode(), and do d += (char)c;. Then your first code snippet will correctly return ALABAMA.

By the way, there needs to be an error check in decode(), verifying that you exit the loop with node equal to root. Otherwise, there were some bits provided that ended in the middle of a code, and so were not decoded to a symbol.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • The tree is right. Both the inorder and postorder traversals match if you run through them again. Also, I added the error check. – Tyler West Nov 24 '18 at 19:22