вектор не работает в структуре

У меня есть такая структура:

struct element{
char ulica[10];
vector<int> dane[3];
int wolne;
int w;
element *lewy, *prawy, *ojciec;
};

И я реализую вид дерева AVL. Когда ключи одинаковы, мне нужно поместить некоторые значения int в датчанин (датчанин [0], датчанин [1], датчанин [2] описывают 3 разных значения), поэтому я использую

tmp2->dane[0].push_back(number)

РЕДАКТИРОВАТЬ. Вот код, в котором я добавляю значения к этому вектору, это половина функции, потому что вторая половина связана с поворотами в AVL.

void wstaw_wezel(){

    element *tmp2; //tmp2 bedzie ojcem nowo wstawionego elementu
    tmp2=korzen;
    while(tmp2!=NULL){
    if(strcmp(tmp2->ulica, tmp->ulica)<0){
        if(tmp2->prawy!=NULL){
            tmp2=tmp2->prawy;
        }
        else{
            tmp->ojciec=tmp2;
            tmp2->prawy=tmp;
            cout<<"Wstawiam pod prawy "<<tmp2->ulica<<endl;
            if(tmp2->w!=0) tmp2->w=0;
            else tmp2->w=-1;
            break;
        }
    }
    else if(strcmp(tmp2->ulica, tmp->ulica)>0){
        if(tmp2->lewy!=NULL){
            tmp2=tmp2->lewy;
        }
        else{

            tmp->ojciec=tmp2;
            tmp2->lewy=tmp;
            if(tmp2->w!=0) tmp2->w=0;
            else tmp2->w=1;
            cout<<"Wstawiam pod lewy "<<tmp2->ulica<<endl;
            break;
        }
    }
    else{
        cout<<"2 bloki na tej samej ulicy"<<endl;
        for(int i=0; i<tmp2->dane[0].size(); i++) cout<<tmp2->ulica<<" "<<tmp2->dane[0][i]<<endl;
        tmp2->numery.push_back(tmp->numery[0]);
        tmp2->dane[0].push_back(tmp->dane[0][0]);
        for(int i=0; i<tmp2->dane[0].size(); i++) cout<<tmp2->ulica<<" "<<tmp2->dane[0][i]<<endl;
        tmp2->dane[1].push_back(tmp->dane[1][0]);
        tmp2->dane[2].push_back(tmp->dane[2][0]);
        tmp2->wolne+=tmp->dane[2][0];
        break;

    }
    }
    if(tmp->ojciec==NULL){
         korzen=tmp;
         return;
    }

где tmp2 — указатель на эту структуру (проверил адрес, куда он указывает, и каждый раз один и тот же адрес).

Где проблема? Если я добавлю новое значение в вектор, это произойдет до тех пор, пока цикл, в котором я это делаю, не закончится. Наконец, вместо того, чтобы иметь fe. 4 значения в векторе у меня есть одно, последнее добавленное значение. Вектор не добавляет новое значение в конец, а просто заменяет его.


person lisek    schedule 30.12.2011    source источник
comment
Не работает - это немного расплывчато. В чем ошибка?   -  person Tom van der Woerdt    schedule 30.12.2011
comment
Вам действительно нужен массив векторов? Опубликуйте минимальный пример кода, изображающий проблему.   -  person Alok Save    schedule 30.12.2011
comment
Пожалуйста, опубликуйте цикл, который вы упомянули.   -  person diggingforfire    schedule 30.12.2011
comment
вы, вероятно, хотите что-то вроде vector‹int› dane; и так что-то вроде tmp2-›dane.push_back(number)   -  person João Augusto    schedule 30.12.2011
comment
Добавлен цикл. Мне нужен массив векторов, а не вектор общего размера 3.   -  person lisek    schedule 30.12.2011
comment
@lisek: я обновил свой ответ ниже. Посмотрите, работает ли это для вас.   -  person andand    schedule 30.12.2011
comment
Похоже, в ваших циклах for отсутствует запись   -  person rlduffy    schedule 30.12.2011


Ответы (2)


Вы объявляете начальный размер std::vector в его конструкторе, поэтому один из способов сделать это:

struct element
{
    char ulica[10];
    std::vector<int> dane;
    int wolne;
    int w;
    element *lewy, *prawy, *ojciec;

    element() : dane(3) {}
};

Если вы не включите конструктор, начальный размер вектора будет равен 0. В любом случае, чтобы добавить элемент сзади, просто используйте tmp2->dane.push_back(number); Это добавит значение в number к задней части вектора tmp2->dane, что может привести к изменению объема выделенной памяти для экземпляра вектора.

ОБНОВЛЕНИЕ: на основании комментария ОП о том, что ему нужны три вектора, попробуйте следующее:

struct element
{
    char ulica[10];
    std::vector<std::vector<int> > dane;
    int wolne;
    int w;
    element *lewy, *prawy, *ojciec;

    element() : dane(3) {}
};

Чтобы добавить элементы к векторам, просто используйте tmp2->dane[i].push_back(number), где i — это индекс используемого вектора, а number — это новое число, которое нужно добавить к ith вектору, что соответствует тому же соглашению, которое вы, кажется, использовать в своем сегменте кода выше.

Обновление 2. Основываясь на приведенной ниже дополнительной информации, я считаю, что требуется перепроектирование вашей структуры данных. Вы смешиваете значения различных компонентов, и, более четко разграничивая функции элемента данных и управления структурой данных AVL, вы сможете более четко различать их. Так что попробуйте это вместо этого. Создайте структуру данных специально для «значительной» части узлов вашего дерева, например:

struct house
{
    int house_number;
    int unique_value0;
    int unique_value1;

    house(int hn, int uv0, int uv2)
        : house_number(hn),
          unique_value0(uv0),
          unique_value1(uv1) {}
};

template <typename VALUE> struct node
{
    std::string key;
    std::vector<VALUE> values;
    int left, right;
    node<VALUE> *leftNode, *rightNode, *parentNode;
};

Отсюда вы создаете корневой узел:

node<house> *root;

Если вы хотите добавить дом к улице, node<house> *s, все, что вам нужно сделать, это

s->values.push_back(house(a, b, c));

Конечно, лучшей альтернативой является использование того, что уже есть в C++. То есть в стандартной библиотеке есть структура под названием std::multimap, которая в значительной степени то, что вы пытаетесь сделать. В этом случае вы можете просто объявить

std::multimap<std::string, house> myMap;

Это, вероятно, не будет использовать балансировку AVL. Скорее всего, это будет красно-черное дерево, но все сделано за вас.

person andand    schedule 30.12.2011
comment
Ничего не изменилось. Для этого значения: 'a 1' 'a 2' 'a 3' 'a 4', a - это ключ, а число int добавляется с помощью push_back, оно печатает: a 1, a 1 a 2, a 2 a 3, a 3 4 и в main перед завершением программы просто напечатайте 4. - person lisek; 30.12.2011
comment
Тогда может показаться, что проблема не в векторе, а в некоторой логике того, как вы используете вектор. Итак, было бы полезно увидеть еще одно редактирование вашего вопроса, в котором более четко описывается ожидаемый результат и чем он отличается от результата, который вы видите. - person andand; 30.12.2011
comment
Могу выслать весь код, но это около 500 строк + один txt файл. Но как насчет логики? Я делаю вектор, использую 4-5 раз push_back, а затем печатаю весь вектор. - person lisek; 30.12.2011
comment
Итак, мне не ясно, что вы ожидаете увидеть от своих результатов. Вы говорите, что есть проблема, но вам нужно четко указать, каковы ваши ожидания от программы и как ее фактическое поведение отличается от ваших ожиданий. В более раннем комментарии вы предоставили некоторые входные данные и некоторые выходные данные. Это часть того, что я ищу. Другая часть должна быть описанием того, как результат отличается от ваших ожиданий. Каким должен быть результат для этого ввода? Вы просто ожидали, что вывод будет таким же, как ввод? - person andand; 30.12.2011
comment
@lisek: Еще одна вещь. Я действительно не вижу в вашем коде того, чего вы пытаетесь добиться с помощью трех векторов. Когда у вас есть несколько значений для данного ключа, почему вы не можете просто хранить дубликаты в одном векторе (который вы можете отсортировать, если хотите)? На самом деле это значительно упростило бы ваш код, если бы вы просто сохранили все значения для определенного ключа в векторе и не различали, когда есть несколько значений для одного ключа. Всегда предполагайте, что будет несколько значений. - person andand; 30.12.2011
comment
Я постараюсь сделать это более ясным. Я создаю AVL, пытаясь сохранить имена улиц в качестве ключа. Я ищу улицу, и если я ее не найду, добавлю ее в дерево, но если я ее найду, я хочу добавить номер дома в вектор, чтобы я мог добраться до каждого дома на этой улице, просто найдите один ключ в дерево. Мне нужно 3 вектора, потому что у одного дома есть своя улица, номер и два других уникальных значения. У меня должна быть функция для поиска дома, поэтому, если я нашел улицу, я могу просмотреть вектор для поиска его номера, тогда у меня есть векторный итератор, и я могу получить 2 других значения. - person lisek; 30.12.2011
comment
@lisek: мне было трудно следовать логике вашей программы, и я до сих пор не уверен, что у вас правильный подход, как описано в вашем комментарии. Я опубликовал несколько возможных советов по редизайну, которые должны упростить определение проблемы, четко разграничив контент, которым вы пытаетесь управлять, и структуру данных, которую вы используете для управления. Когда вы пытаетесь сделать слишком много вещей одновременно, логикой становится трудно управлять, и она очень подвержена ошибкам. Лучше разделить части и разрабатывать и тестировать их независимо друг от друга. - person andand; 31.12.2011
comment
Я попробую этот метод, но я не знаю, как печатать fe. каждый номер_дома. указатель-›значения[итератор] и что теперь? - person lisek; 31.12.2011
comment
Мой код, опубликованный как вопрос, работает хорошо, но я ошибся, если это разрушит всю идею. Кстати, спасибо. - person lisek; 02.01.2012
comment
Без проблем. Удачи в остальной части вашего проекта. - person andand; 02.01.2012

Как вы выделяете элемент структуры? Кажется, что vector<int> dane[3]; был успешно инициализирован, но его внутренний вектор не был инициализирован.

попробуйте добавить метод ctor в struct element?

struct element 
{
    char ulica[10];
    vector<int> dane[3];
    int wolne;
    int w;
    element *lewy, *prawy, *ojciec;

    element()
    {
        dane[0] = vector<int>();
        dane[1] = vector<int>();
        dane[2] = vector<int>();
    }
};
person Xuezhe Liu    schedule 08.02.2017