![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| asmdzen |
|
||||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
Нужен контейнер с уникальными элементами как в map'е но с возможностью применять сортировку по разным принципам в разное время.
например у меня есть структура типа
нужна возможность указать контейнеру таких структур или указателей на них отсортировать весь контейнер по определенному элементу структуры (ip, input_count), при добавлении новых элементов они уже будут сортироваться по новому принципу. что у меня получилось:
как организовать сортировку по определенному принципу непонятно, может есть какое-то стандартное решение или кто-то с этим уже работал? Добавлено через 11 минут и 45 секунд приходит на ум только изменять поведение "operator'а <" в структуре, вызывать сорт для пересортировки, новые элементы уже будут добавятся на основании этих изменений. при добавлении нового элемента - ищем первый элемент больший нужного нам, вставляем перед ним. Это сообщение отредактировал(а) asmdzen - 26.6.2011, 23:17 |
||||
|
|||||
| afiskon |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 294 Регистрация: 31.3.2011 Где: Россия, Москва Репутация: 1 Всего: 4 |
Используйте несколько map'ов или set'ов для сортировки по каждому ключу.
|
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Основной контейнер самого простого типа, какой позволяет задача (вектор или список), для хранения элементов, + сколько надо индексов, которые сортируют указатели.
-------------------- ... |
|||
|
||||
| Сыроежка |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 127 Регистрация: 24.6.2011 Репутация: нет Всего: 1 |
Почему вы у опреатора функции не указали квалификатор const? А вообще-то вы навертели всего так много, что без компилятора под рукой трудно разобраться. Как я понял, вы используете контейнер std::set лишь для проверки уникальности элементов в контейнере std::list. Вам фактически нужно соритровать лишь список. Какие в связи с этим вопросы? Если я не ошибаюсь (под рукой нет шпаргалки), то контейнер std::list имеет функции-члены сортировки. В крайнем случае вы можете воспользоваться стандартным алгоритмом сортировки std::sort. Как задать различные условия? Используете алгоритм сортировки с предикатом, где в качестве предиката указывайте любые условия, какие вам придут в голову. Вы же уже умеете писать оператор функцию. Фактически, предикат и составляет оператор функцию, либо непосредственно можете указывать различные функции члена класса, содержащие требуемые условия. При сортировке вам в вашу функцию будут передаваться два элемента вашего класса. Вы можете сравнивать любые их поля. То есть вы для своего класса пишите функцию-обертку либо для встроенной сортировки в контейнере list либо для стандартного алгоритма std::sort. Ее шаблон копируете на основе стандартного шаблона функции сортировки. Шаблонным типом будет лишь только предикат Примерно так (без всяой проверки):
|
||||
|
|||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
для алгоритма std::sort необходим контейнер с произвольным доступом. ни std::list, ни тем более наследник от std::list таким не является. asmdzen, воспользуйтесь советом от Earnest Это реально рабочий и наиболее эффективный способ. Это сообщение отредактировал(а) volatile - 29.6.2011, 01:52 |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Почему тем более-то? -------------------- ... |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
а уникальность? не хочется после каждого insert делать sort (сейчас так работает), думаю более подходящим для меня является именно то что показал Сыроежка, у list'а есть собственный sort, который может сортировать по operator < или по объекту comparator'у. Всем спасибо за помошь. П.С. не балуюсь такими ограничителями ) |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
какая разница ? Если список в каждый момент времени уже отсортирован, можно либо ручками, либо каким-нибудь std::merge вставлять элемент в "своё" место. По идее это будет занимать log2(N) операций. зря, батенька, зря © самизнаетекто -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
спасибо, я об этом не подумал, хотя наверное посмотрю как он работает и прикручу свой, не брать ведь для этого еще один list.
сами ведь merge предложили ) т.е. sort я конечно сделаю но только после подмены operator'а <, а для обычной вставки уже merge. |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
не люблю велосипедов, но в данном случае, думаю, ты прав: у merge интерфейс совершенно не удобный для твоей задачи -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| Сыроежка |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 127 Регистрация: 24.6.2011 Репутация: нет Всего: 1 |
Вообще-то, на мой взгляд правильнее было бы делать не производный класс от std::list, а сделать std::list членом вашего класса точно также, как вы сделали членом класса std::map.
Это сообщение отредактировал(а) Сыроежка - 29.6.2011, 19:12 |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
std::set?
не хочется еще тысячу методов добавлять, просто убрал мешающие и все, пускай все остальные методы list'a останутся (не разобрался еще какие нужны, какие нет). было бы просто замечательно если можно было бы работать с полями структур, или просто указывать контейнеру из хранимого элемента какая часть является идентификатором(id) определяющий уникальность элементов и указывать по какой части сортировать элементы. .пока писал пришла мысль, какая-то внешняя функция которая и указывает это, т.е. ей передается указатель на элемент который следует добавить, она возвращает id и ключ по которому нужно сравнивать. эту функцию и можно менять на ходу.
в общем идея была не плоха ( понятия не имею как это реализовать, подумаю еще. |
|||
|
||||
| borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
кста, уже обсуждали и довольно подробно -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
borisbn, ну не знаю, вроде правильно наследую, мне ведь нужно еще один контейнер прикрепить, да и передавать этот новый контейнер потом можно как std::list.
а если подумать то получается std::map с возможностью sort'а (автоматического в том числе), поищу может найду что-то подобное. |
|||
|
||||
| spyswamp |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
Для этого уже придумали boost::multi_index::multi_index_container. Не надо изобретать велосипеды. -------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
||||
|
||||
| spyswamp |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
baldina, а чего там тяжелого? Собери 1 lib-ину, и все. Весят они совсем чуть-чуть, а пользы приносят достаточно. Или ты имел ввиду "тяжелый для понимания"?
-------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
| baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
я имел в виду, что не всегда удобно, целесообразно или просто возможно тянуть за собой либы. или даже использовать кучу просто хидеров.
буст рулит, но не надо фанатизма |
|||
|
||||
| spyswamp |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
baldina, понятное дело. Но по мне, так лучше использовать проверенные решения, чем ковыряться в отладчике. Это я к тому, что сейчас поддерживаю кучу адового кода с самописными итераторами, смарт_птрами, листами и т.п. от таких нефанатов. Знать КАК это работает нужно, я не спорю, но вот использовать в чем-то, кроме школьных или институтских лабораторных, все же, не стоит. Embedded systems не рассматриваем сейчас, там свои замуты.
-------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
В любом проверенном решении могут быть ошибки - программирование однако. И чем сложнее решение, тем вероятнее ошибки и сложнее их обнаружить и просто понять причину проблемы. Я в бусте ошибки находила. Данная же задача довольно тривиальна для проприентарного случая (я имею в виду контейнер + разные индексы). А вот гибкое (бустовское) решение может быть достаточно сложным. Не буду утверждать, что это именно так, ибо не знакома с этим контейнером. Но запрограммировать упомянутый проприентарный контейнер - полчаса, ну час от силы. И ради чего огород городить-то? Т.е. Подписываюсь. -------------------- ... |
|||
|
||||
| spyswamp |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
Earnest, простите, конечно, но "огород" - это именно ваше решение.
-------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это только если руки растут сами знаете откуда, чего там программировать-то Это если имеешь опыт работы с данным классом или концепцией. А если нет (нельзя же все знать!), то чтобы разобраться и привыкнуть, нужно некоторое время, и это совсем не полчаса. А автор топика, похоже, не знает, иначе не спрашивал бы. -------------------- ... |
|||
|
||||
| spyswamp |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 349 Регистрация: 18.8.2006 Репутация: 1 Всего: 7 |
Ладно-ладно, вы меня затроллили.
-------------------- - why you call it beta? - cuz it's betta then nothin' |
|||
|
||||
| asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: нет Всего: 5 |
всем спасибо, после "effective c++" стало понятно что не так с наследованием от list'а, немного пересмотрел задачу и оказалось что совет Earnest самый подходящий (не буду мудрить).
boost тоже не плох, только с ним еще надо разобраться. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |