Найдите, какие числа больше всего отображаются в векторе
У меня есть некоторые числа, хранящиеся в векторе . Я хочу найти какое число появится в векторе.
есть ли простой / быстрый алгоритм (STL или что-то еще), который делает это ?
4 ответов
сортируйте его, затем повторите его и сохраните счетчик, который вы увеличиваете, когда текущее число такое же, как и предыдущее, и сбросьте до 0 в противном случае. Также следите за тем, какое было наибольшее значение счетчика до сих пор и какое текущее число было, когда это значение было достигнуто. Это решение O(n log n)
(из-за сортировки).
в качестве альтернативы вы можете использовать hashmap от int до int (или, если вы знаете, что числа находятся в ограниченном диапазоне, вы можете просто использовать array) и перебирать вектор, увеличивая the_hashmap[current_number]
по 1 для каждого номера. Затем выполните итерацию через hashmap, чтобы найти его наибольшее значение (и принадлежащий ему ключ). Для этого требуется структура данных hashmap (если вы не можете использовать массивы, которые также будут быстрее), которая не является частью STL.
Если вы хотите избежать сортировки вектора v
используйте карту:
int max = 0;
int most_common = -1;
map<int,int> m;
for (vi = v.begin(); vi != v.end(); vi++) {
m[*vi]++;
if (m[*vi] > max) {
max = m[*vi];
most_common = *vi;
}
}
это требует больше памяти и имеет очень похожее ожидаемое время выполнения. Требуемая память должна быть в порядке полной векторной копии, меньше, если есть много повторяющихся записей.
вот как я это сделал:
int max=0,mostvalue=a[0];
for(i=0;i<a.size();i++)
{
co = (int)count(a.begin(), a.end(), a[i]);
if(co > max)
{ max = co;
mostvalue = a[i];
}
}
Я просто не знаю, насколько это быстро, т. е. O ()? Если бы кто-то мог вычислить его и опубликовать здесь, это было бы хорошо.
вот O (n) общее решение для поиска наиболее распространенного элемента в диапазоне итераторов. Вы используете его, просто делая:
int commonest = most_common(my_vector.begin(), my_vector.end());
тип значения извлекается из итератора с помощью iterator_traits<>
.
template<class InputIt, class T = typename std::iterator_traits<InputIt>::value_type>
T most_common(InputIt begin, InputIt end)
{
std::map<T, int> counts;
for (InputIt it = begin; it != end; ++it) {
if (counts.find(*it) != counts.end()) {
++counts[*it];
}
else {
counts[*it] = 1;
}
}
return std::max_element(counts.begin(), counts.end(),
[] (const std::pair<T, int>& pair1, const std::pair<T, int>& pair2) {
return pair1.second < pair2.second;})->first;
}