![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
День добрый !
Есть задачка: имеется структура
нужно хранить в некоем контейнере такие структуры, но только уникальные. Т.е. чтобы выполнялось условие (псевдокод)
вроде бы идеально подходит std::set, но он требует operator< для структуры, а меня это не устраивает по двум причинам: 1. Мне совершенно не важно, будут ли структуры храниться в отсортированном виде, т.к. их количество будет 20...30 и добавление в контейнер будет происходить только в начале программы. А время поиска конкретного элемента для данной задачи совершенно не критично. 2. Я не знаю как сравнить две структуры на предмет меньше ли одна или нет, т.к. оба поля в принципе равнозначны. Смотрел на QSet (Qt), но он требует ф-цию хеша из моей структуры, а я тем более не представляю, как её сделать... Можно, конечно, повелосипедировать: аггрегировать вектор и написать ф-цию добавления и поиска... но хочется сначала выяснить, нет ли готового решения Спасибо. P.S. boost просьба не предлагать соответствующего coder'а прошу не обижаться Это сообщение отредактировал(а) borisbn - 24.6.2011, 10:41 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| rudvil |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Если есть поддержка C++0x
--------------------
xor |
|||
|
||||
| Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
||||
|
||||
| rudvil |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 155 Регистрация: 20.11.2009 Где: Latvia/Riga Репутация: 2 Всего: 3 |
Точно... это же не POD. Спасибо за поправку. --------------------
xor |
|||
|
||||
| Sahab |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
мне только непонятно... если
то чем не подходит?
|
||||
|
|||||
| RastaDja |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 337 Регистрация: 1.11.2010 Репутация: нет Всего: 5 |
потому что a и b - несут независимую информацию например а - масса, b - высота какой объект больше? - тот что тяжелее, или выше? -------------------- The more closely you look at one thing, the less closely can you see something else. |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
в принципе, я уже дошёл до этого, но, т.к. мне действительно не важно, то можно и return true сделать... то, что можно так заюзать set - я уже понял (мало того, уже сделал), но хотелось бы выяснить не будет ли это overhead'ом? Нет ли стандартного (специально обученного, заточенного) решения для этой задачи. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 81 Всего: 211 |
ни в коем случае.
|
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
azesmcar, спасибо. Я правильно понял, что return true нельзя, т.к. set (ну или там алгоритмы поиска - не важно) может вместо operator== создать собственный
и тогда он просто не найдёт нужный мне элемент, а при return false будет всегда находить первый ? Что тогда посоветуете ? P.S. Откуда цитата ? Это сообщение отредактировал(а) borisbn - 24.6.2011, 13:21 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Earnest |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это неправильно, нужно так:
Сравнение обязательно должно быть транзитивным, иначе в твоем сете будет каша. Есть много случаев, когда упорядочивание нужно чисто для хранения. Логический смысл тогда не важен, главное, чтобы упорядочивание было однозначным и непротиворечивым. Если POD, как у тебя, и не содержит double, тогда я не парюсь, а просто использую memcmp. Условие, которое привел azesmcar, автоматически выполняется. Кстати, можно тогда не писать свой == (потому что он уже есть - !< && !>). Кстати, если определить свою структуру через std::pair (вместо именованных членов), то оператор сравнения генерируется автоматически, именно как я написала. Естественно, если сравнение для членов не определено, возникают проблемы... Другое дело, если стандартный оператор < не подходит, как например для даблов... Для засовывания в хэш-контейнеры таких структур (из 2 чисел, можно и double) использую комбинацию с простыми числами, типа
Могут быть и другие числа (не помню уже откуда, давно содрала и с тех пор счастливо использую); разбрасывает замечательно, даже если точки близки. Но только имей в виду, что хэш обычно жрет памяти побольше, чем просто map\set. Если это важно. -------------------- ... |
||||||
|
|||||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Earnest, я для примера вривёл 2 поля. На самом деле у меня их 6. Представляешь, что за монстр получится в операторе < ?
не то, чтобы можно, а бессмысленно, т.к., судя по всему, std::set использует только меньше. Говорю это потому, что определил только оператор меньше, и у меня всё скомпилялось и добавление и поиск... -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Sahab |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 151 Регистрация: 1.9.2009 Репутация: нет Всего: 3 |
это и ежу понятно... но в данном контексте это было не важно |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
важно Sahab,
тем, что если a1 < a2, а b1 > b2, то обе структуры будут считаться больше другой. Может и зацикливание произойти. Это сообщение отредактировал(а) borisbn - 24.6.2011, 14:24 -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Earnest |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Скомпилировалось - не значит правильно работает. Чего бы не скомпилироваться, если формальный синтаксис соблюден. Еще раз, приведенный в самом начале оператор < - неправильный, потому что не транзитивный. Можешь нарваться не сразу, и будешь долго ломать голову, откуда лажа. Грубо говоря, даже уникальность хранения может нарушаться при таком операторе: все зависит от того, в каком состоянии будет дерево и по какому пути пойдет сравнение. Если членов много, и это POD, можно использовать memcmp, как я писала.
set действительно использует только "меньше". Я имела в виду, что может сравнение на равенство нужно тебе зачем-то еще. Да не намного страшнее, чем оператор проверки равенства - принцип тот же, упорядочиваешь по первой, если она равна - по второй и т.д. Только удобнее записать немного по-другому:
Ну или хэш-контейнеры использовать. -------------------- ... |
||||||
|
|||||||
| borisbn |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
хммммм. а ведь идея:
Добавлено через 9 минут и 19 секунд это то понятно (чай не первый раз замужем). под "скомпилировалось" я имел в виду, что std::set больше ничего не требует. и не более того.
теперь ясно. нет. не нужен. тогда такой вопрос:
-------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||||
|
|||||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |