Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> деревья с неизвестным количеством потомков. 
:(
    Опции темы
tonchitos
Дата 11.3.2008, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



Идея такая, нужно дерево с неизвестным количеством классов потомков.
То есть у меня дерево, размеры которого нужно менять и количество потомков каждого потомка тоже, по желанию.

Ну у меня идея сделать полем дерева список, а дальше что, в общем, у кого какие едеи, поделитесь.


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
andrew_121
Дата 11.3.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33





--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
korian
Дата 11.3.2008, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



например так:
Код
#include <vector>

template <class T>
class Tree : public std::vector<Tree>
{
public:
   T data;
};



Это сообщение отредактировал(а) korian - 11.3.2008, 17:32
PM   Вверх
Lazin
Дата 11.3.2008, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



korian, стандартные контейнеры не предназначены для наследования,
Каждый узел бинарного дерева может содержать произвольное количество потомков, несмотря на то, что указателя всего 2... просто у дерева рекурсивная природа, и потомки определенного узла, находятся в различных отношениях друг с другом, они упорядочены.То-есть мы можем взять любой узел и определить как он соотносится с каждым из своих потомков.  А если сделать список, то это уже сложно будет внятно использовать... смысла такая структура не имеет  smile


Это сообщение отредактировал(а) Lazin - 12.3.2008, 08:44
PM MAIL Skype GTalk   Вверх
maxim1000
Дата 11.3.2008, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



а я бы всё-таки делал контейнер (список, вектор или ещё что-либо, в зависимости от параметров задачи) потомков в каждом узле
с помощью бинарного дерева, конечно, можно реализовать любое другое, только это не означает, что нужно

P.S.
начать стоит с того, чтобы подумать, как было бы удобно работать с этим деревом, например, написать несколько фрагментов кода, как будто дерево уже реализовано, оттуда и плясать

Это сообщение отредактировал(а) maxim1000 - 11.3.2008, 18:14


--------------------
qqq
PM WWW   Вверх
korian
Дата 11.3.2008, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(Lazin @  11.3.2008,  16:44 Найти цитируемый пост)
стандартные контейнеры не предназначены для наследования

это где такое написано?
Цитата(Lazin @  11.3.2008,  16:44 Найти цитируемый пост)
А если сделать список

то что я предложил, является деревом с произвольным количеством child'ов и любой глубины.

короче, что-то я, наверно, не понял задачу и до сих пор не понимаю.


Это сообщение отредактировал(а) korian - 11.3.2008, 19:08
PM   Вверх
SABROG
Дата 11.3.2008, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 4
Всего: 91



Я обычно делаю так. Действительно беру за основу контейнер типа vector. Создаю свою структуру добавляю членом - контейнер, объявляю другие необходимые структуры, которые также могут содержать контейнеры и через new выделяю указатели, которые и пихаю в контейнеры. Потом пробегаюсь по контейнерам и вызываю delete на указатели структур. Поэтому удобно вынести это в класс, удаление добавить в деструктор. А в конструкторе можно формировать само дерево.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
korian
Дата 11.3.2008, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



объясните, пожайлуста, кто-нибудь чем вас не устраивает, то что я написал.

Tree t; - корень дерева
t.push_back(Tree()); - добавляем дочерний узел
t.begin()...t.end() - дочернии узлы узла t;
t.data - данные, соответствующие узлу t;
(*(*t.begin()).begin()) - дочерний узел дочернего узла узла t;
и не надо самому заморачиваться с выделением/удалением памяти.

что еще надо?

Это сообщение отредактировал(а) korian - 11.3.2008, 22:05
PM   Вверх
maxim1000
Дата 11.3.2008, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



хранить вектор из просто узлов, а не указателей чревато большими накладными расходами:
если у нас есть большое дерево, и мы хотим добавить где-то на верхнем уровне ещё один узел, операция push_back время от времени будет приводить к перевыделению памяти и копированию всех элементов
если дерево большое, безобидная операция может сильно затянуться
ну а если не хочется помнить об освобождении памяти, можно использовать умные указатели...

Добавлено через 7 минут и 44 секунды
касательно наследования от вектора:
у него нет виртуального деструктора
это значит, что возможна такая ситуация:
A наследуется от std::vector
где-то создаётся объект класса A
потом куда-то передаётся по указателю на std::vector
потом к нему кто-то применяет delete
из-за отсутствия виртуального деструктора у вектора, деструктор A и его полей не будет вызван, что может вызвать проблемы

тут, конечно, никто не предполагает, что объекты будут уничтожаться через указатель на вектор, но в большинстве более-менее долго разрабатываемых программ появится ситуация, когда это покажется удобным

чаще всего если можно сделать композицией или наследованием, лучше делать композицией - проще получается...



--------------------
qqq
PM WWW   Вверх
korian
Дата 11.3.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(maxim1000 @  11.3.2008,  22:26 Найти цитируемый пост)
операция push_back время от времени будет приводить к перевыделению памяти и копированию всех элементов

решаеться заменой vector на list

Цитата(maxim1000 @  11.3.2008,  22:26 Найти цитируемый пост)
у него нет виртуального деструктора

ну это просто необходимо помнить
или проще класс Tree обернуть в что-то подобное умного указателя, и не давать создавать/уничтажать объект пользователям, чтобы не возникали проблемы с этим.


Это сообщение отредактировал(а) korian - 11.3.2008, 23:55
PM   Вверх
tonchitos
Дата 12.3.2008, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



Если честно, я с контейнерами не знакома.
Вот щас почитаю, конечно. Если можно, разьясните мне преимущества контейнера в данном случае.
korian, вы все верно поняли, мне дейсвительно это и нужно:

Цитата(korian @  11.3.2008,  19:01 Найти цитируемый пост)
является деревом с произвольным количеством child'ов и любой глубины.


Если вам не очень трудно, дайте мне побольше пояснений как это будет работать, я с контейнерами не работала.
Простите за беспокойство  smile 


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 12.3.2008, 03:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



там ошибка была и заменим vector на list
Код

#include <list>

template <class T>
class Tree : public std::list<Tree<T> >
{
public:
   T data;
};


Цитата(tonchitos @  12.3.2008,  00:06 Найти цитируемый пост)
преимущества контейнера в данном случае

только в том, что класс дерево создается 5-ю строчками.

Цитата(tonchitos @  12.3.2008,  00:06 Найти цитируемый пост)
Если вам не очень трудно, дайте мне побольше пояснений как это будет работать, я с контейнерами не работала

переписывать хелп по контейнерам нету желания
поищите, думаю на форуме много примеров использования <list>
основное, как использовать это дерево я писал выше.
по конкретным функциям могу ответить...

Это сообщение отредактировал(а) korian - 12.3.2008, 04:02
PM   Вверх
Lazin
Дата 12.3.2008, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



стандартные контейнеры не предназначены для наследования еще и по тому что у них нет protected членов, то-есть наследуя от вектора или списка мы по сравнению с композицией ничего не выигрываем, а только добавляем зависимость, так-как теперь код работающий с Tree зависит от интерфейса контейнера, что не есть гуд... вообще наследованием увлекаться не стоит
подробно это описано у Мейерса...
хранить в контейнере лучше все-таки указатели, желательно умные)), так-как элементы контейнера не обязательно будут простыми структурами, возможно узлом дерева будет что-то имеющее таблицу виртуальных функций))

теперь о деревьях...

      5
    /   \
  2     7
  /\    /\
 1 4 6  9

вот упорядоченное бинарное дерево.. теперь вопрос, а как может быть упорядочено дерево с более чем 2-мя потомками.. объясните мне))

единственное применение, на мой взгляд, это всякие иерархические структуры данных, элементы которых находятся в отношениях родитель - потомок, например GUI библиотеки... там элемент управления(кнопка например) может принадлежать другому элементу управления и при удалении родителя должен быть удален и потомок. Или например DOM представление XML документа...
PM MAIL Skype GTalk   Вверх
Mayk
Дата 12.3.2008, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(korian @  12.3.2008,  03:52 Найти цитируемый пост)

ну это просто необходимо помнить
или проще класс Tree обернуть в что-то подобное умного указателя, и не давать создавать/уничтажать объект пользователям, чтобы не возникали проблемы с этим.

Зачем героически преодолевать собственные грабли, если их можно банально не разбрасывать?




--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
korian
Дата 12.3.2008, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(Lazin @  12.3.2008,  08:08 Найти цитируемый пост)
а как может быть упорядочено дерево с более чем 2-мя потомками.. объясните мне))

Код

#include <list>

template <class T>
class Tree : public std::list<Tree<T> >
{
public:
   operator < (const Tree<T> & node) {return data < node.data};
   void sort()
   {
       std::list<Tree<T> >::sort();
       for (Tree::iterator i = begin(); i != end(); i++)
          i->sort();
   }
   T data;
};

void main()
{
    Tree<int> root;
    ....
    root.sort();
}


Цитата(Mayk @  12.3.2008,  08:39 Найти цитируемый пост)
Зачем героически преодолевать собственные грабли, если их можно банально не разбрасывать?

потому что написание дерева с нуля, содержит на много больше граблей, включая и эти (или похожие).


Это сообщение отредактировал(а) korian - 12.3.2008, 16:28
PM   Вверх
tonchitos
Дата 12.3.2008, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



и еще, дерево должно быть из элементов сложных, ну я имею в виду что узел дерева должен быть структурой с несколькими полями данных.


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
Lazin
Дата 12.3.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



тогда уж проще использовать просто list<T>, который будет сортироваться за то-же время что и твое дерево
к тому-же узел дерева у которого есть итераторы, методы insert, push_back и тд. выглядит не как узел дерева, а как список(он и есть список)
PM MAIL Skype GTalk   Вверх
tonchitos
Дата 12.3.2008, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



вот вставила в прогу кусок с листом, ошибки...

Compiling...
Tree.cpp
1>d:\toncitos\tree\tree\metreestruct.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>        d:\toncitos\tree\tree\metreestruct.h(19) : see reference to class template instantiation 'Tree_C<T>' being compiled
1>d:\toncitos\tree\tree\metreestruct.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>        d:\toncitos\tree\tree\tree.cpp(111) : see reference to class template instantiation 'Tree_C<T>' being compiled
1>        with
1>        [
1>            T=int
1>        ]
1>Generating Code...
1>Compiling...
1>TreeView.cpp
1>Generating Code...
1>Compiling...
1>AddNewChild.cpp
1>MainFrm.cpp
1>TreeDlg.cpp
1>TreeDoc.cpp
1>Generating Code...
1>Compiling...
1>MeTreeStruct.cpp
1>d:\toncitos\tree\tree\metreestruct.h(11) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>        d:\toncitos\tree\tree\metreestruct.h(19) : see reference to class template instantiation 'Tree_C<T>' being compiled


Это сообщение отредактировал(а) tonchitos - 12.3.2008, 23:38


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 12.3.2008, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(Lazin @  12.3.2008,  15:47 Найти цитируемый пост)
тогда уж проще использовать просто list<T>, который будет сортироваться за то-же время что и твое дерево
к тому-же узел дерева у которого есть итераторы, методы insert, push_back и тд. выглядит не как узел дерева, а как список(он и есть список) 

вообще-то, я там sort листа и использую, только там сортировка углубляеться.
не нравяться названия методов - сделайте inline обертку - это быстрее, проще и безопаснее, чем писать с нуля.

обратите, пожайлуста, внимание:
template <class T>
class Tree : public std::list<Tree<T> >

Tree<int> t;
можна написать как:
list<list<list<list.....<list<int> > >......> t; //(возможно бесконечное число вложений. хотя так его описать нельзя, т.к. к каждому листу еще надо присоединить int data)

извените конечно, но узел он и есть список.
можна конечно делать такое дерево (узел содержит 3 списка).
struct node
{
    node* next;
    node* firstChild;
    node* parent;
}

но если устраивает такое (что у меня вообщем то и есть):
struct
{
    node* firstChild;
}
т.е. единственно, узел не знает о родителе и соседних клетках, а в большинстве случаев в этом нету необходимости (обход дерева идет с корня).
а если все же надо передвигаться по дереву снизу вверх, можна добавить в класс Tree инфу о родителе.

Цитата
и еще, дерево должно быть из элементов сложных, ну я имею в виду что узел дерева должен быть структурой с несколькими полями данных.

это дерево может работать с любыми данными

Цитата(tonchitos @  12.3.2008,  16:38 Найти цитируемый пост)
вот вставила в прогу кусок с листом, ошибки...

дайте листинг кода и номер строки на которой ошибка.

Это сообщение отредактировал(а) korian - 12.3.2008, 18:12
PM   Вверх
tonchitos
Дата 12.3.2008, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



ошибка тут

operator < (const Tree_C<T> & node) {return data < node.data};

код? у мя проект большой.... только если весь проект.
Тк в этом файле ниче кроме этого контейнера.


Я так и не пойму как это ботает, ну разьясните плиз.

примерчик еще хочу


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 12.3.2008, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



operator < (const Tree_C<T> & node) {return data < node.data};
тут ; не там стоит
operator < (const Tree_C<T> & node) {return data < node.data;}

листинг я имел ввиду, листинг класса Tree
и строку как объявлен объект класса.

PM   Вверх
tonchitos
Дата 12.3.2008, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



не помогло...


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 12.3.2008, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



создание бинарного дерева, по типу, как это делалось тут: http://forum.vingrad.ru/forum/topic-200066.html

Код

void MakeTree (Tree<int>& node, int n)
{
    node.data = n;
    int n1, n2;
    if ( n == 1 ) return;//ограничение рекурсии
    n1 = n / 2;//размеры левого 
    n2 = n - n1 - 1;//и правого поддеревьев
    node.push_back(Tree<int>());
    MakeTree(*(--node.end()));
    if (n2 > 0)
    {
       node.push_back(Tree<int>());
       MakeTree(*(--node.end()));
    }
    return Tree;
}


Tree<int> root;
MakeTree(root, 20);


Добавлено через 2 минуты и 20 секунд
дайте вот это:
листинг я имел ввиду, листинг класса Tree
и строку как объявлен объект класса.
что за компилятор
и вообще, ICQ есть? а то сейчас это все растянется на кучу страниц.
PM   Вверх
korian
Дата 12.3.2008, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



понял в чем ошибка, плюс нашел еще одну, из-за которой сортировка не могла работать.
Код

#include <list>

template <class T>
class Tree : public std::list<Tree<T> >
{
public:
   inline bool operator < (const Tree<T> & node) {return data < node.data;}
   void sort()
   {
       std::list<Tree<T> >::sort();
       for (Tree::iterator i = begin(); i != end(); i++)
          i->sort();
   }
   T data;
};

template <class T>
inline bool operator < (const Tree<T> & node1, const Tree<T> & node2) {return node1.operator < (node2);}


PM   Вверх
tonchitos
Дата 12.3.2008, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



на работе мне предложили так:

Код

namespace GUI
{
    class Node 
    {
        std::vector<Node> childs;
        std::string Name;
    public:
    
    int GetNumChilds ()
    {
    
        return childs.size();
    }
    const Node & GetChild (int pos) const
    {
        return childs[pos];
    }

    Node & GetChild (int pos)
    {
        return childs[pos];
    }

    bool insertChild (int pos, Node & element );
    bool removeChild (int pos);
    operator = (cont Node & from);
    }

}


тут с ошибками...

чем этот вариант лучше или хуже?

Добавлено @ 23:33
korian, ваш вариант загружается таки теперь  smile 

Это сообщение отредактировал(а) tonchitos - 12.3.2008, 23:34


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 12.3.2008, 23:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(tonchitos @  12.3.2008,  22:30 Найти цитируемый пост)
чем этот вариант лучше или хуже?

лучше, тем что названия функций имеют осмысленные названия.
а хуже тем, что используеться vector (про это раньше писалось, чем плохо), и в данном варианте жесткая привазка к нему.
все остальное, можна сказать, один к одному 
PM   Вверх
tonchitos
Дата 13.3.2008, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



мне сказали что лист не имеет ф-ии childs.size(); в отличие от вектора.
 smile 


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 13.3.2008, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



size у листа есть, у него нету доступа к елементам по индексу
PM   Вверх
tonchitos
Дата 13.3.2008, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



ясно...

и еще, я понимаю, что надоела уже наверно.

Но как лучше сохранить в файл это дерево?
 smile 


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
Mayk
Дата 13.3.2008, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(korian @  12.3.2008,  19:12 Найти цитируемый пост)

потому что написание дерева с нуля, содержит на много больше граблей, включая и эти (или похожие).

Ситуация А) мы создаём дерево и наследуем его от list'а, это приводит к нарушению инкапсуляции так как теперь дерево может запросто быть преобразовано в list, там где это не надо.

Ситуация Б) мы создаём дерево и не наследуем его от list'а, это не приводит к нарушению инкапсуляции так как теперь дерево не может запросто быть преобразовано в list, там где это не надо.

Инкапсуляцию вижу, грабли  не обнаружены. 

Цитата(korian @  13.3.2008,  04:44 Найти цитируемый пост)
size у листа есть, у него нету доступа к елементам по индексу 

Грабли вижу, инкапсуляция не обнаружена. Меня как пользователя дерева не колышет что есть у листа а что нет. Если у него нет доступа к i-ому элементу, это его личные проблемы. меня как пользователя дерева они вообще не должны  волновать.

Цитата(korian @  13.3.2008,  03:57 Найти цитируемый пост)

а хуже тем, что используеться vector (про это раньше писалось, чем плохо), и в данном варианте жесткая привазка к нему.

Не надо вводить человека в заблуждение. PImpl сюда прикручивается в несколько пинков, а с ним клиентский код ВООБЩЕ не будет зависеть от листов/векторов/деков.   В случае с наследованием от листа/вектора/дека сделать код не зависимым от базового типа НЕВОЗМОЖНО в принципе. Поэтому про жесткую привязку --- это относится к наследованию нежели к композиции.




--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
tonchitos
Дата 13.3.2008, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



Mayk, то есть вы за тот пример который мне на работе предложили?


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
Mayk
Дата 13.3.2008, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(tonchitos @  13.3.2008,  14:12 Найти цитируемый пост)
Mayk, то есть вы за тот пример который мне на работе предложили? 

Да, мы за него. Он значительно лучше наследования. И он не зависит от вектора в том смысле, что когда ты работаешь с деревом, ты всегда можешь 
использовать GetChild(), а не соображать "а реализован ли operator[] у вектора или позавчера мы заменили vector на list и поэтому наш tree[4] сегодня валится с дымом и едким запахом"

Это сообщение отредактировал(а) Mayk - 13.3.2008, 10:39


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
maxim1000
Дата 13.3.2008, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 17
Всего: 110



на тот случай, если под аргументами против вектора понимаются мои слова, то поясню конкретнее:
дело не в том, вектор или список или ещё что-то
дело в том, что хранится в контейнере
если что-то запихиваешь в вектор, нужно быть готовым к копированию этого объекта
и если дерево будет большим, это может привести к неожиданным и непонятным оверхедам

так что при условии использования вектора я бы посоветовал хранить в нём указатели (обычные или умные - другой вопрос), чтобы избежать ненужного копирования больших объёмов данных

Это сообщение отредактировал(а) maxim1000 - 13.3.2008, 12:58


--------------------
qqq
PM WWW   Вверх
tonchitos
Дата 13.3.2008, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



перегружаю оператор =.
почему то ошибка.

не пойму где:

Код

namespace GUI
{
    class Node 
    {
        std::vector<Node> childs;
        std::string Name;
    
    public:
    .......
        .......
    
        void operator = (const Node & from);

    
    };

}


Код


void GUI::Node::operator =(const GUI::Node &from)
{
    GUI::Node::childs = from;
}


Это сообщение отредактировал(а) tonchitos - 13.3.2008, 14:01


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
Lazin
Дата 13.3.2008, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



оператор присваивания обычно выглядит так:
Код

Node& operator = (const Node & from);

и вот здесь:
Код

GUI::Node::childs = from;

нужно написать вот так
Код

if (&from == this) return *this;
childs = from.childs;
Name = from.Name;
return *this;

PM MAIL Skype GTalk   Вверх
Mayk
Дата 13.3.2008, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(Lazin @  13.3.2008,  18:14 Найти цитируемый пост)
if (&from == this) return *this;
childs = from.childs;
Name = from.Name;
return *this;

если не заменить vector<Node> на vector<Node*> как сказал maxim1000, то делать оператор присваивания большого смысла нет --- компилятор и сам напишет.


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
tonchitos
Дата 13.3.2008, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



Код

void CADlg::OnButton4()
{
// TODO: Add your control notification handler code here CFile theFile;
theFile.Open("tree.sav",CFile::modeCreate| CFile::modeWrite);
CArchive ar(&theFile,CArchive::store);

HTREEITEM hti = m_tree.GetRootItem();
while(hti)
{
int indent = GetIndentLevel(hti);
while(indent--)
ar.WriteString("\t");
ar.WriteString(m_tree.GetItemText(hti)+"\r\n");
hti= GetNextItem(hti);
}

ar.Close();
theFile.Close();
} 


вот пример, но он сохраняет банально текст.

Это сообщение отредактировал(а) tonchitos - 13.3.2008, 16:49


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
tonchitos
Дата 13.3.2008, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



ответьте уже кто нить!

плиз  smile 


--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
korian
Дата 13.3.2008, 17:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Прочитав лекцию Mayk, хочу согласиться с тем, что включение контейнера в класс намного лучше наследования.
В свое оправдание могу лишь сказать, что на тот момент, я не рассматривал такой вариант. (вариант предложен не был, а мой моск до этого чета не дошел  smile  ).
В варианте с наследованием, все проблемы можна решить, но по сравнению с вариантом композиции, это действительно будет "героическое преодоление собственных граблей".
По поводу жесткой привязки, я имел ввиду то, что данная реализация, а именно доступ к элементу по индексу, привязывает к вектору. Если уходить от вектора к листу из-за перевыделения памяти, то получаем увеличенное время для доступа к элементу.

Цитата(tonchitos @  13.3.2008,  16:04 Найти цитируемый пост)
ответьте уже кто нить!

в каком виде его сохранить то надо?
PM   Вверх
tonchitos
Дата 13.3.2008, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 24.2.2007

Репутация: нет
Всего: 40



мне тут один человек предложил следующий вариант:
Код



namespace GUI
{
     template <typename T>
     class Node 
     {
          std::vector<Node> childs;
          Node* parent;
          static int level = 0;
     public:
          T data;
          void printToFile( File file )
          {  file.write( *new container<T>( data );
             Node::level++;
             for (по всем childs) childs[i].printToFile( file );
             Node::level--;
          }
...............
...............
.............
};

    template <typename T>
    class container
    {
       public: container( T d ) : data( d ), level( Node::level ) {}
         int level; // уровень в дереве
         T data;
    };
}



--------------------
– Люди забыли эту истину, – сказал Лис, – но ты не забывай: ты навсегда в ответе за всех, кого приручил.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0893 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.