【发布时间】:2010-03-21 22:08:30
【问题描述】:
我有一些数字存储在std::vector<int> 中。我想找出向量中出现最多的数字。
例如在向量中
1 3 4 3 4 2 1 3 2 3
出现次数最多的元素是3。
是否有任何算法(STL 或其他)可以做到这一点?
【问题讨论】:
我有一些数字存储在std::vector<int> 中。我想找出向量中出现最多的数字。
例如在向量中
1 3 4 3 4 2 1 3 2 3
出现次数最多的元素是3。
是否有任何算法(STL 或其他)可以做到这一点?
【问题讨论】:
对它进行排序,然后遍历它并保留一个计数器,当当前数字与前一个数字相同时递增,否则重置为 0。还要跟踪到目前为止计数器的最高值是多少,以及达到该值时的当前数字是多少。这个解决方案是O(n log n)(因为排序)。
或者,您可以使用从 int 到 int 的 hashmap(或者如果您知道数字在有限范围内,您可以只使用数组)并遍历向量,将 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 FindMode(vector<int> value)
{
int index = 0;
int highest = 0;
for (unsigned int a = 0; a < value.size(); a++)
{
int count = 1;
int Position = value.at(a);
for (unsigned int b = a + 1; b < value.size(); b++)
{
if (value.at(b) == Position)
{
count++;
}
}
if (count >= index)
{
index = count;
highest = Position;
}
}
return highest;
}
【讨论】:
这就是我的做法:
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;
}
【讨论】:
if来简化它,但它仍然是O(nlogn)