Имеется набор элементов. На нем определена операция сравнения, но довольно бедная: не "<" и ">", а только "==" и "!=". Одна задача: разбить этот набор на классы эквивалетнтости. Вторая — от каждого класса оставить только по одному элементу. Получается, что мне нужно что-то вроде std::multiset (для первой задачи) и std::set (для второй) на множестве, в котором не задан порядок. В STL таких контейнеров нет. Может вам известны библиотеки, реализующую данную функциональность?
Спасибо.
Здравствуйте, pasenger, Вы писали:
P>Имеется набор элементов. На нем определена операция сравнения, но довольно бедная: не "<" и ">", а только "==" и "!=". Одна задача: разбить этот набор на классы эквивалетнтости. Вторая — от каждого класса оставить только по одному элементу. Получается, что мне нужно что-то вроде std::multiset (для первой задачи) и std::set (для второй) на множестве, в котором не задан порядок. В STL таких контейнеров нет. Может вам известны библиотеки, реализующую данную функциональность? P>Спасибо.
Если оператор == производит сравнение на принадлежность к тому или иному классу, то задача может быть решена за O(NxC), где N число объектов, а С — число классов, причем в результирующее "множество" попадут первые попавшие представители класса:
std::vector<object> source;
std::vector<object> result;
for(std::vector<object>::const_iterator is = source.begin(), es = source.end(); is!=es; is++)
{
bool found = false;
for(std::vector<object>::iterator ir = result.begin(), er=result.end(); ir!=er; ir++)
if( (found = *is == *ir) )
break;
if( !found )
result.push_back(*is);
}
Здравствуйте, Анатолий Широков, Вы писали:
АШ>Если оператор == производит сравнение на принадлежность к тому или иному классу, то задача может быть решена за O(NxC), где N число объектов, а С — число классов, причем в результирующее "множество" попадут первые попавшие представители класса:
<skiped />
Спасибо. Насколько я понимаю, вы разбираетесь в алгоритмах. Не подскажите, к какому классу задач относится данная. Вероятно, мне что-нибудь еще придется делать с таким множеством (в котором, не задан порядок). Какие-нибудь ключевые слова для гугла.
Здравствуйте, pasenger, Вы писали:
P>Имеется набор элементов.
А можно ли определить хеш-функцию?
Если до то тогда можно использовать хеш-таблицы что будет гораздо быстрее тупого перебора.
Они хоть еще и не попали в тандарт но есть во многих реализациях STL.
См hash_set, hash_multiset, hash_map, hash_multimap.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, pasenger, Вы писали:
P>Имеется набор элементов. На нем определена операция сравнения, но довольно бедная: не "<" и ">", а только "==" и "!=". Одна задача: разбить этот набор на классы эквивалетнтости. Вторая — от каждого класса оставить только по одному элементу. Получается, что мне нужно что-то вроде std::multiset (для первой задачи) и std::set (для второй) на множестве, в котором не задан порядок. В STL таких контейнеров нет. Может вам известны библиотеки, реализующую данную функциональность? P>Спасибо.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, Анатолий Широков, Вы писали:
RO>>>Вот к чему приводит боязнь goto… АШ>>А по существу дела у вас есть что сказать?
RO>По существу я вообще-то привел свой вариант реализации алгоритма, более оптимальный.
Вы привели более кратную реализацию алгоритма, возможно, но оптимальную ли?
P>>Имеется набор элементов. WH>А можно ли определить хеш-функцию?
Или хотя бы оператор <. Попробуй посмотреть на реализацию operator== у айтема, может возникнут какие-то идеи. Без оператора < в худшем случае разбиение на классы эквивалентности будет O(N^2) (если в каждом классе всего по одному элементу). С оператором < сможешь использовать std::multiset, и будешь иметь сложность O(N*logN).
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, pasenger, Вы писали:
P>>Имеется набор элементов. WH>А можно ли определить хеш-функцию? WH>Если до то тогда можно использовать хеш-таблицы что будет гораздо быстрее тупого перебора. WH>Они хоть еще и не попали в тандарт но есть во многих реализациях STL. WH>См hash_set, hash_multiset, hash_map, hash_multimap.
Хеш-функция это частность. Более общая постановка вопроса сводится к следующему: можно ли изменить интерфейс объекта так, чтобы каждый объект сообщал о классе, к которому он принадлежит. В этом случае, можно было построить и хеш-функцию и оператор < и пр.
Здравствуйте, Анатолий Широков, Вы писали:
WH>>А можно ли определить хеш-функцию? WH>>Если до то тогда можно использовать хеш-таблицы что будет гораздо быстрее тупого перебора. WH>>Они хоть еще и не попали в тандарт но есть во многих реализациях STL. WH>>См hash_set, hash_multiset, hash_map, hash_multimap.
АШ>Хеш-функция это частность. Более общая постановка вопроса сводится к следующему: можно ли изменить интерфейс объекта так, чтобы каждый объект сообщал о классе, к которому он принадлежит. В этом случае, можно было построить и хеш-функцию и оператор < и пр.
К сожалению, это всё COM: и элементы, и оператор "==" (ф-я equal, если точнее)
> Или хотя бы оператор <. Попробуй посмотреть на реализацию operator== у айтема, может возникнут какие-то идеи. Без оператора < в худшем случае разбиение на классы эквивалентности будет O(N^2) (если в каждом классе всего по одному элементу). С оператором < сможешь использовать std::multiset, и будешь иметь сложность O(N*logN).
Если я ничего не перепутал, то O(N*logN) у сета/мультисета получается только в среднем, в худшем случае будет тоже O(N^2).
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, Sergey, Вы писали:
>> Или хотя бы оператор <. Попробуй посмотреть на реализацию operator== у айтема, может возникнут какие-то идеи. Без оператора < в худшем случае разбиение на классы эквивалентности будет O(N^2) (если в каждом классе всего по одному элементу). С оператором < сможешь использовать std::multiset, и будешь иметь сложность O(N*logN).
S>Если я ничего не перепутал, то O(N*logN) у сета/мультисета получается только в среднем, в худшем случае будет тоже O(N^2).
>> Или хотя бы оператор <. Попробуй посмотреть на реализацию operator== у айтема, может возникнут какие-то идеи. Без оператора < в худшем случае разбиение на классы эквивалентности будет O(N^2) (если в каждом классе всего по одному элементу). С оператором < сможешь использовать std::multiset, и будешь иметь сложность O(N*logN).
S>Если я ничего не перепутал, то O(N*logN) у сета/мультисета получается только в среднем, в худшем случае будет тоже O(N^2).
В set-multiset поиск имеет логарифмическую сложность всегда. Поэтому квадрата не получится в любом случае. Получится O(N*logN) в хужшем случае (в каждом классе всего по одному элементу) и O(N) в лучшем (все элементы принадлежат одному классу).