如何从向量或数组中选择最常见的数字?(前五名)C++
How to select the most common numbers from a vector or on array?(TOP5 toplist) C++
我有一个整数向量。我想选择最常见的数字。我想列出前 5 名。例如:
std::vector<int> numbers = {32, 32, 32, 12, 12, 11, 11, 11, 9};
最常见的数字是:前 1:32、前 2:11、前 3:12、前 4:9;
选择它们后,我想将其存储到另一个向量中:最常见的数字。
这是另一种算法,对于任何k
,成本将是O(n(,再加上一个体面的缓存位置。
1.首先将所有元素存储在unordered_map
O(N(中
std::unordered_map<int, int> m;
for(const auto ele: numbers) {
m[ele]++;
}
2.转储 O(N( 对向量中的所有元素
std::vector<std::pair<int, int>> temp;
for(const auto& ele: m) {
temp.emplace_back(ele.first , ele.second);
}
3.现在使用nth_element找到第k个等级O(N(
std::nth_element( temp.begin(), temp.begin()+k ,
temp.end(), [](const auto& p1, const auto& p2) {
// Strict weak ordering
if (p1.second > p2.second) {
return true;
} if (p1.second < p2.second) {
return false;
}
return p1.first > p2.first; // We have to print large element first
} );
4.显示输出
std::for_each( temp.begin(), temp.begin() +k - 1, [](const auto & p) {
std::cout << p.first << " ";
});
在这里演示
您可以创建一个unordered_map<int,int> mp
,您可以在其中存储每个数字的计数,如mp[32] = 3
。
接下来你需要找到前五个元素
-
时间复杂度 : O(mlogm( :您可以按降序对地图进行排序(要对其进行排序,您必须使用额外的向量(,并获取前 5 个元素。
-
时间复杂度: O(m( :或者您可以在整个地图上迭代 5 次以获得顶部文件元素。每次迭代时,都要找到频率最高的数字,而该数字尚未出现在我们的 topFive 向量中。
m :映射中的条目数。
我已经做了这个例子,并把注释放在了内联中。它至少需要 C++11。
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
int main(void) {
std::map<int, int> ans;
std::vector<int> numbers = {32, 32, 32, 12, 12, 11, 11, 11, 9};
std::vector<std::pair<int, int>> sorted;
std::vector<int> common;
// Step 1 Accumulate into a map, counting occurrences
for (auto number : numbers) {
ans[number]++;
}
// Step 2 Make a linear list, putting the count first then the value
for (auto& ent : ans) {
sorted.emplace_back(ent.second, ent.first);
}
// Step 3 sort it, by count ascending
std::sort(std::begin(sorted), std::end(sorted));
// Step 4 Get commonest 5 (or fewer)
for (int i = 1; i<= 5; ++i) {
int index = sorted.size() - i;
if (index >= 0) {
common.push_back(sorted[index].second);
}
}
// Step 5 print out
for (auto i : common) {
std::cout << i << std::endl;
}
return 0;
}
你可以这样做:创建一个集合,这样你就可以摆脱重复的,然后在向量中找到集合中每个项目的频率,用这个结果创建一个对(类似于int,int(在向量中推送该对,最后使用你自己的谓词对其进行排序:
现在对于顶部x,你可以做一个for循环,或者只是调整向量的大小,如果你确定这样做的后果是什么是。
std::vector<int> numbers{32, 32, 32, 12, 12, 11, 11, 11, 9};
std::set<int> mySet(numbers.begin(), numbers.end());
std::vector<std::pair<int, int>> result{};
for(const auto& x : mySet)
{
result.push_back(std::make_pair(x , std::count(numbers.begin(), numbers.end(), x)));
}
std::sort(result.begin(), result.end(), [](const std::pair<int, int>& a, const std::pair<int, int>& b){return (b.second < a.second);});
//result.resize(3);
std::cout << "Top: " << std::endl;
for(const auto& x : result)
{
std::cout << x.first << ':' << x.second << std::endl;
}
结果将是:
顶部:11:3 32:3 12:2 9:1
有很多方法可以实现这一点。其中之一可能是。
std::vector numbers = {32, 32, 32, 12, 12, 11, 11, 11, 9};
int maxNumber = *std::max_element(numbers.begin(), numbers.end())
std::vector<int> occurrences(maxNumber + 1, 0);
for(auto& value : numbers)
{
occurrences[value]++;
}
然后,您只需要在跟踪索引的同时对数组进行排序。这是C++索引排序和跟踪的另一个问题的主题 .
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 检查输入是否不是整数或数字
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 如何用数字处理log(0)
- 最高有效数字侧的第N位
- 如何获取一个数字的前3位
- 查找最接近的大于当前数字的数字的索引
- 找到两对数字,使它们的乘积的绝对差最小化
- 我想做一个彼此不同但重复出现的数字
- 将数字转换为字母(例如:123 转换为一二三)
- C++如何计算用户输入的数字中的偶数位数
- 如何在C++中确定文本文件中的元素是字符还是数字
- 打印数字图案
- C++问题:用户认为数字1-100,程序提出问题不超过6次即可得到答案。无法正确
- 如何检查一个c++字符串中有多少相同的字符/数字
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 将数字打印成文字
- 当使用比格式支持的精度更高的精度来显示数字时,会写出什么数据
- 在将数字随机生成为数组期间从内存输出随机数的数组