Рекурсивная функция-член не может получить доступ к своим собственным переменным - PullRequest
0 голосов
/ 13 сентября 2011

Я начинаю с верхнего узла дерева глубиной 5 слоев и рекурсивно вызываю getvalue () для каждого.Каждый узел связан с двумя узлами на следующем уровне.Я уверен, что это не моя проблема, так как я дважды проверил алгоритм на бумаге.Однако, как только я доберусь до уровня 3, это вызовет ошибку сегментации.С помощью valgrind я понял, что он возник, когда я пытался напечатать переменную класса oper.Я понятия не имею, куда идти с этим, поэтому ваша помощь очень ценится.Это код:

class Node {
    public:
        vector<Node> children;
        long constval;
        char oper;
        void setconst();
        Node();
        void copy(const Node*);
        int getvalue();
    private:
        int mult(int,int);
        int div(int,int);
        int add(int,int);
        int sub(int,int);
};

Node::Node() {
    bool c = false;
    vector<char> operations;
    operations.push_back('m');
    operations.push_back('a');
    operations.push_back('s');
    operations.push_back('d');
    operations.push_back('c');
    constval = rand();
    int randnum = rand() % 5;
    cout << randnum << "\n";
    oper = operations[randnum];
}

int Node::getvalue() {
    cout << oper << '\n';
    if (oper == 'm') {
        return Node::mult(children[0].getvalue(), children[1].getvalue());
    }
    else if (oper == 'd') {
        return Node::div(children[0].getvalue(), children[1].getvalue());
    }
    else if (oper == 'a') {
        return Node::add(children[0].getvalue(), children[1].getvalue());
    }
    else if (oper == 's') {
        return Node::sub(children[0].getvalue(), children[1].getvalue());
    }
    else if (oper == 'c') {
        return constval;
    }
}

РЕДАКТИРОВАТЬ: Вот мой инициализирующий алгоритм:

class Individual {
    public:
        vector< vector<Node> > nodes;
        vector< vector<Node> > getrand();
        void replace(vector< vector<Node> >);
        void mutate(double);
        double run();
        Individual();
};

Individual::Individual() {
    nodes.resize(5);
    nodes[0].resize(1);
    int size = 2;
    for(int i = 1; i < 5; i++) {
        nodes[i].resize(size);
        size = size * 2;
    }
    vector<char> operations;
    operations.push_back('a');
    operations.push_back('s');
    operations.push_back('d');
    operations.push_back('m');
    nodes[0][0].oper = operations[rand() % 4];
    for(int x = 0; x < nodes[4].size(); x++) {
        nodes[4][x].setconst();
    }
    for(int i = 0; i < 4; i++) {
        for(int x = 0; x < nodes[i].size(); x++) {
            nodes[i][x].children.push_back(nodes[i+1][x*2]);
            nodes[i][x].children.push_back(nodes[i+1][x*2+1]);
        }
    }   
}

Ответы [ 3 ]

1 голос
/ 13 сентября 2011
vector<Node> children;

У меня такое же мнение, как и у Андрея; что мне также не нравится использование вектора в качестве контейнера дочерних узлов. Если ваша структура данных представляет собой простое двоичное дерево, почему бы просто не использовать

Node* leftChild;
Node* rightChild;

как члены данных класса Node?

Также, пожалуйста, предоставьте код для создания вашего дерева. Вероятно, вы допустили некоторую ошибку, поскольку ошибка сегментации, скорее всего, связана с неправильным созданием структуры данных, и вы, возможно, этого не осознавали.

0 голосов
/ 13 сентября 2011

Вы никогда не проверяете, есть ли у вашего узла дочерние элементы.

0 голосов
/ 13 сентября 2011
  1. На первый взгляд кажется, что последний слой вашего дерева должен содержать только цифры.Но это не гарантируется алгоритмом.

  2. На самом деле, я не люблю векторы как дочерний контейнер.Почему бы не использовать два указателя?Кроме того, я не вижу, где вы инициализируете вектор и помещаете в него дочерние элементы.

  3. Посмотрите, как работает rand().

...