Название: Замапить 2 контейнера Отправлено: Igors от Июнь 04, 2017, 08:45 Добрый день
Есть 2 контейнера (возможно с разным числом эл-тов). Для каждого эл-та в первом нужно найти какой ему соответствует во втором по ключам (ID + Name) или наоборот (Name + ID), порядок ключей задается юзером. Ключи не уникальны. Порядок поиска - находим с таким же ID и Name - иначе находим хотя бы с таким же ID - иначе просто берем первый неиспользуемый из 2-го контейнера Найденный во втором эл-т не может использоваться для поиска других эл-тов. Нет ограничений на число проходов поиска - напр первый проход ищет "полное" совпадение, второй только первый ключ и.т.д. Как это сделать "техничнее", по возможности избегая длинного и нудного кода? И еще: квадратичный перебор не запрещается (вряд ли эл-тов будет мульены), но все-таки хотелось бы без него (мы же приличные люди :)) Спасибо Название: Re: Замапить 2 контейнера Отправлено: Авварон от Июнь 04, 2017, 18:49 Не очень понятно, почему вы упомянули, что порядок ID и Name может быть разный? Разве это не независимые поля структурки?
Первый неиспользуемый == один из тех, что остались незаюзанными после маппинга? Что делать, если неиспользуемых нет? Название: Re: Замапить 2 контейнера Отправлено: Johnik от Июнь 04, 2017, 19:24 можно глянуть boost multi_index_container
Название: Re: Замапить 2 контейнера Отправлено: Racheengel от Июнь 05, 2017, 00:24 Проще всего создать дополнительные индексы (мапы) для 2 контейнера.
Например что то типа typedef QPair<QString,QString> id_name_index; QMap<id_name_index, item_index> index_map; В index_map сложим все индексы элементов второго контейнера, определяемые парой индексов. Далее "все элементарно". Один вопрос только: что значит "берем первый неиспользуемый из 2-го контейнера"? Название: Re: Замапить 2 контейнера Отправлено: Igors от Июнь 05, 2017, 11:08 Не очень понятно, почему вы упомянули, что порядок ID и Name может быть разный? Разве это не независимые поля структурки? Поля независимые, порядок (приоритет) нахождения разный - противоречий нетПервый неиспользуемый == один из тех, что остались незаюзанными после маппинга? ДаЧто делать, если неиспользуемых нет? Ничего. Да, в первом может быть 10, во втором только 5 (или наоборот). Ну значит 5 и остались незамаплнены, невозможного не требуетсяможно глянуть boost multi_index_container Когда-то читал, не очень понимаю как он здесь может пригодитьсяПроще всего создать дополнительные индексы (мапы) для 2 контейнера. Я тоже попытался мудрить в этом духе, но потом вставил флажок прямо к ключ и if в оператор < :) Например что то типа typedef QPair<QString,QString> id_name_index; QMap<id_name_index, item_index> index_map; В index_map сложим все индексы элементов второго контейнера, определяемые парой индексов. Далее "все элементарно". Скорее "тривиально" :) Но увы - длинновато. Получается 3 прохода, на каждом эл-т ищется в std::set и удаляется если найден. Может есть что покруче?Один вопрос только: что значит "берем первый неиспользуемый из 2-го контейнера"? Не понял - ну то и значит, первый (по порядку) которые еще не был замаплен на эл-т первого контейнервНазвание: Re: Замапить 2 контейнера Отправлено: deMax от Июнь 05, 2017, 11:52 Скорее "тривиально" :) Но увы - длинновато. Получается 3 прохода, на каждом эл-т ищется в std::set и удаляется если найден. Может есть что покруче? В set у вас храниться только id/имя? я бы второй массив, в два map с ключом по индексу и по имени засунул; а значение указатель на элемент во втором массиве и флаг использования. перебор ~ 3*n*log(n) для каждого элемента в первом массиве находим через map соответствия, и так 3 прохода. Можно для красоты в свой map обернуть, типа такого DuoMap<T1 key1, T2 key2, T value> и методы find(key1,key2), find(key1). p.s. Еще можно таблицы в БД хранить, там своя оптимизация, вряд ли будет быстрее но кода будет меньше. Название: Re: Замапить 2 контейнера Отправлено: Igors от Июнь 05, 2017, 12:37 Ключ такой получился
Код Для первого контейнера - вектор таких ключей с mEntryIndex = -1 (не найдено). Для второго - std::set таких ключей с mEntryIndex = i (индекс во втором). Ну и 3 прохода. |