Вот как можно подсчитать вхождения чего-либо из чего угодно:
Код
#include <iterator>
#include <map>
#include <algorithm>
template<class InputIt>
auto
occurrences(InputIt begin, InputIt end)
{
std::map<typename std::iterator_traits<InputIt>::value_type, std::size_t> result;
std::for_each(begin, end, [&result](auto const& item){ ++result[item]; });
return result;
}
Использование
#include <string>
#include <iostream>
int main()
{
auto text = std::string{"Hello, World!"};
auto occ = occurrences(begin(text), end(text));
std::cout << occ['l'] << '\n'; // outputs 3
}
Демонстрация в реальном времени
Пояснение
template<class InputIt>
Это универсальная (шаблонная) функция, повторяющаяся на любом входном итераторе.
auto
Тип возвращаемого значения выводится из его реализации.Оповещение о спойлере: это std::map
of (счетчик значений, вхождение этого значения).
occurrences(InputIt begin, InputIt end)
occurrences
вызывается с помощью пары итераторов, определяющих диапазон, обычно вызывающих begin(C)
и end(C)
на вашем контейнере C
.
std::for_each(begin, end, //...
Для каждого элемента в диапазоне ...
[&result](auto const& item){ //...
... выполните следующую обработку ...
++result[item]; });
... увеличить счетчик вхождений для значения item
, начиная с нуля, если оно является первым.
Это не реализация эффективного , поскольку она копирует значенияэто считается.Для целых чисел, символов, и т. Д. это идеально, но для сложных типов вы можете улучшить эту реализацию.
Это универсальный и стандартный контейнер, совместимый.Вы можете посчитать что-нибудь итерируемое.