Есть аналог контейнера из питона collections.Counter() в qt/c++? Мне нужно

отсортировать список объектов по частоте использования. Как можно красиво и быстро вытащить вытащить самых частых объектов?
Мой минимальный вариант на картинке.

15 ответов

26 просмотров

Хм. Предложение: Делаешь функтор-обертку над интом. В конструкторе - зануляешь, в operator() возвращаешь rvalue на инт. Тип так: class my_int { int val = 0; public: my_int() = default; ~my_int() = default; int& operator()() { return val; }; } Дальше делаешь template<typename T> class mycounter : public std::vector<std::pair<<T, my_int>> { public: void sort() { std::sort(begin(), end(), [](const value_type& left, const value_type& right) { return left.second() < right.second(); }); }; } На этом всё. Из минусов, перед перебором надо вызывать метод sort. В коде могут быть ошибки, набирал с телефона, но думаю идея понятна?

Мгер-Карапетян Автор вопроса
Пашечка
Хм. Предложение: Делаешь функтор-обертку над инто...

Спасибо за ответ, идея понятная. Вот только мне нужно что бы объекты не дублировались внутри контейнера(то есть быстрый поиск по ключу и уже изменение его значения).

Можно попробовать положить все в один вектор, и сортировать в зависимости от потребностей. И держать контейнер отсортированным так, чтобы было быстрее делать те операции, которые чаще нужны. Если, например, заранее известно, что сначала в контейнер делается много insert, а после этого уже только одни mostCommon, то можно после завершения добавления элементов переключить сортировку, и больше не трогать. https://godbolt.org/z/PWf5x9cd4

Мгер-Карапетян Автор вопроса
Ананданатх
Можно попробовать положить все в один вектор, и со...

Спасибо, очень красивый код. Почему по умолчанию не использовать map вместо vector?

Мгер Карапетян
Спасибо, очень красивый код. Почему по умолчанию н...

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

экономный вариант без лишнего копирования ключей может выглядеть так: #include <QDebug> #include <QList> #include <QString> #include <map> #include <span> #include <vector> class Histogram { using CounterMap = std::map<QString, int>; CounterMap m_counter; mutable bool m_invalidated = false; mutable std::vector<CounterMap::const_iterator> m_order; public: void append(QString key) { m_counter[std::move(key)]++; m_invalidated = true; } std::span<CounterMap::const_iterator> top(size_t n = 0) const { if (m_invalidated) { reorder(); } if (!n) { n = m_counter.size(); } return std::span(m_order.begin(), n); } private: void reorder() const { m_order.clear(); m_order.reserve(m_counter.size()); for (auto&& it = m_counter.begin(); it != m_counter.end(); ++it) { m_order.emplace_back(it); } std::sort(m_order.begin(), m_order.end(), [](auto&& a, auto&& b) { return b->second < a->second; }); m_invalidated = false; } }; int main(int, char*[]) { Histogram historam; QList<QString> keys { "one", "two", "three", "one", "three", "one" }; for (auto&& key : keys) { historam.append(key); } auto&& top = historam.top(); for (auto&& e : top) { qDebug() << e->first << e->second; } }

Мгер-Карапетян Автор вопроса
Anatoly Shirokov
экономный вариант без лишнего копирования ключей м...

О спасибо, и про гистограммы помните) вопрос по коду, что это: decltype(m_order)().swap(m_order); почему просто не m_order.clear();?

Мгер Карапетян
О спасибо, и про гистограммы помните) вопрос по ко...

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

Мгер-Карапетян Автор вопроса
Anatoly Shirokov
это старый трюк освободит память вектора, clear мо...

ну зачем же убирать, буду учиться, может встречу в коде и буду знать что оно делает) а так спасибо)

Мгер-Карапетян Автор вопроса
Anatoly Shirokov
это старый трюк освободит память вектора, clear мо...

а еще вопрос, у меня Qt5.15.2 MinGW64, в qmake пишу CONFIG += c++latest # c++2a а std::span все равно не находит. Что делаю не так?

Мгер Карапетян
а еще вопрос, у меня Qt5.15.2 MinGW64, в qmake пиш...

значит g++ в mingw64 старичек и не понимает span

Anatoly Shirokov
значит g++ в mingw64 старичек и не понимает span

Немного оффтоп: я почитал про span и немного недогнал, а чем он лучше, например, вектора ссылок?

Anatoly Shirokov
вектора ссылок не бывает

Ладно, справедливо. Заменим на вектор указателей, производительность та же, просто юзать неудобно)

Похожие вопросы

Обсуждают сегодня

Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
сделал сайт, прикрутил в боте сайт, и виджет логина. как автоматически логинить пользователя в аккаунт(телеграм), при входе с бота?
Александра Чернивецкая
5
Объясните, пожалуйста, почему компилятор ругается на использование в условии неинициализированной переменной: int x; Task.Run(async () => { x = await somefunc(); }).Wait...
Александр
5
Ребят, подскажите, пожалуйста, почему в префиксе к ассетам, которые генерируются через фильтр | theme в шаблоне, стал вдруг появляться index.php? Вот так выглядит ссылка на а...
Виталий
1
Всем привет. Ребята, подскажите, пожалуйста. у ботов есть ограничение на отправку сообщений - 30 сообщений в секунду, эти ограничения накладываются на все сообщения? или на со...
Artem Stormageddon
4
Блин, ребята, сори за тупые вопросы. А можно ли как-то открыть вебапку по нажатию на кнопку в меню(которое появляется слева, команды)?
Artem Stormageddon
3
а плаксы из-под питона умеют только в комфортных условиях что-то выдавить из себя?)
Lencore
9
Но, может, есть уже проверенная? Наши требования такие: 1. Сообщения должны приходить из Инста в CRM оду 2. Должна быть возможность подключить несколько экаунтов Инстаграм. Р...
Alexander Sharoiko MSE / Александр Шаройко
13
Это может быть все-таки не флудвейт? у меня ботфазер принимает изменения и отображает даже что они изменились, на видео видно что он прислал якобы уже измененное описание, н...
OVERLINK
13
Коллеги, может знает кто, можно ли цвет бейджа счётчика в BackendMenu менять без бубнов?
Alex Blaze
3
Карта сайта