-2

i have Java decision tree code to pass in C++. I don't remember well the logical inside pointers when i try to build the tree. Java code:

public class Node {
Node parent;
Node children[];
List<Instance> instances;
....
};

Node(Node parent, List<Instance> instances) {
        this.parent = parent;
        children = new Node[Instance.FTSVALUERANGE];
        this.instances = instances;
        ....
 }

For tree generation:

public class ID3 {
Node root;
...

public static Node generate(List<Instance> instances) {
        Node root = new Node(null, instances);
        expand(root, 0);
        return root;
    }
static void expand(Node node, int depth) {
             ...
            ArrayList<ArrayList<Instance>> ts = new ArrayList<ArrayList<Instance>>();
             ...
            /* Grow the tree recursively */
        for (int i = 0; i < Instance.FTSVALUERANGE; i++) {
            if (ts.get(i).size() > 0) {
                node.children[i] = new Node(node, ts.get(i));
                expand(node.children[i], depth + 1);
            }
}}}

And Here my c++ implementation; Node:

class Node
{
    public:
        Node();
        Node(Node* parent, std::vector<Instance>& instances);
        Node* parent;
        Node** children;
        std::vector<Instance> instances;

    ....
};

Node::Node()
{
    parent=NULL;
    children=NULL;
}
Node::Node(Node* parent, std::vector<Instance>& instances) {
        this->parent = parent;
        this->children = new Node*[Instance::FTSVALUERANGE];
        this->instances = instances;
      ...
 };

For tree generation:

class ID3{
  Node* root;
  static void expand(Node* node, int depth);
  static Node* generate(vector<Instance> instances);
  ...
  };
  Node* ID3::generate(vector<Instance> instances) {
    Node* root = new Node(NULL, instances);
    expand(root, 0);// when use ID3.chi_square_100// there is no prunning,
    return root;
 }
 void ID3::expand(Node* node,int depth){
 ...
      for (int i = 0; i < Instance::FTSVALUERANGE; i++) {
            if (ts[i].size() > 0) {
                node->children[i] = new Node(node, ts[i]);
                expand(node->children[i], depth + 1);
            }
    }}}

When i try to run something not works with children. The full implementation is here:https://courses.cs.washington.edu/courses/cse446/12wi/ps/hw4/ID3.java
I have made some changes for my purpose.
Thanks in advance.
Giuseppe.

giuseppe trubia
  • 142
  • 1
  • 13
  • 1
    Why are you implementing your own data structures? I suggest you their use the data structures already available in Java and C++ or at least read the implementations so you understand how they work. Writing them from scratch when you don't understand them is going to be an enormous waste of time (and bugs) If you have a bug in your program, I suggest using your debugger to find it. – Peter Lawrey Jan 10 '16 at 16:38
  • Don't use `NULL`, use `nullptr` instead. Don't use pointer to pointer, and use smart pointer such as `unique_ptr` and use `std::vector` for dynamic lists. – Guillaume Racicot Jan 10 '16 at 16:40
  • Hello @GuillaumeRacicot, Thanks for you help. What do you mean for " Don't use pointer to pointer, and use smart pointer such as unique_ptr" ? – giuseppe trubia Jan 11 '16 at 10:06
  • 1
    A pointer to pointer is a variable declared like `Node**`. It is used sometime as an array to pointer ( since pointers can add well be arrays ) but it's usually a bad idea, because it's usage is error prone and without proper care can lead to memory errors, especially with newcomers in the language. In C++, you have tools like the `std::vector` which is a dynamic array class. – Guillaume Racicot Jan 11 '16 at 13:02
  • I said use smart pointer because again, it's easy to make mistake when dealing with manual memory management. I suggest you to look at the class `std::unique_ptr`, which enforce rule of memory management at compile time, and instead of runtime error you get compile time error. But the best advice I can give you is to read tutorial such as http://www.learncpp.com – Guillaume Racicot Jan 11 '16 at 13:08
  • thanks @GuillaumeRacicot! i change type of children with a `std::vector` and solve another issue in matrix initialize (not default in c++) and now all works. – giuseppe trubia Jan 11 '16 at 17:33

1 Answers1

0

Thanks to Guillaume Racicot for advices!
This is the code:
In Node.cpp:

class Node
{
public:
    Node();
    Node(Node* parent, std::vector<Instance>& instances);
    Node* parent;
    std::vector<Node*> children;
    ....
};

Node::Node(Node* parent, std::vector<Instance>& instances) {

    this->parent = parent;
    this->children= std::vector<Node*>(Instance::FTSVALUERANGE);
    ...
}
giuseppe trubia
  • 142
  • 1
  • 13