您的位置:首页 > 其它

求一个数组中出现次数前k种的元素

2017-08-02 13:42 162 查看
map<string, int> fruitCount;//创建map对象
for (int i = 0; i < sizeof(fruits) / sizeof(fruits[0]); ++i)
{
map<string, int>::iterator it = fruitCount.find(fruits[i]);//创建map迭代器
if (it != fruitCount.end())//先查找看该字符数组内是否存在该字符串
{
it->second++;//给该类对象的计数+1
}
else
{
fruitCount.insert(pair<string, int>(fruits[i], 1));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13

缺点:如果map中没有要插入的这个水果,则需要遍历两次map。

思路二:只遍历一次map 

insert的返回值pair。既然不管是否插入成功,它都能返回我们需要的这个元素的迭代器。那么,我们可以先插入,然后对其返回值进行保存,如果该返回值得第二个参数是true,表示插入成功,不进行其他操作,如果为flase,表示插入失败,那么其返回的第一个参数将会带回已经存在的这个被插入元素的迭代器,当然轻而易举就可以通过迭代器拿到这个元素的第二个参数V。
void CalculateFruitCount(map<string,int>& m, string fruits[], size_t size)
{
for (size_t i = 0; i < size; i++)
{
//m[fruits[i]]++;    //map中有operator[]的重载,其内容等同于下边代码

pair<map<string, int>::iterator, bool> ret;
ret = m.insert(make_pair(fruits[i], 1));
if (ret.second == false)
ret.first->second++;
}
}
1
2
3
4
5
6
7
8
9
10
11
12

现在走到这里已经全部插入了,那接下来我们就需要找前K个最喜欢的水果了。

思路一: 

将统计好的数据全部放入一个vector中,并且利用排序算法sort进行排序。而其默认为升序,最大的则位于数组后边,但是我们并不知道vector有多大。所以,我们采用降续,这样最大的永远在vector的前列.
void GetBeginOfThreeFruits(map<string, int>& m, vector<map<string, int>::iterator>& v)  //按照水果出现的次数降续存储于v中
{
map<string, int>::iterator it = m.begin();

while (it != m.end())
{
v.push_back(it);
it++;
}

struct Compare   //仿函数(降续)
{
bool operator()(map<string, int>::iterator l, map<string, int>::iterator r)
{
return l->second > r->second;
}
};

sort(v.begin(), v.end(),Compare());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

思路二:给一个堆,这个堆只要K个大小。 

因为找出现次数最多的,所以这里给一个小堆。堆顶元素为最小的数。每一次新进来的数字和堆顶比较,如果比堆顶小则不要。比堆顶大则把堆顶pop,把这个元素插入再重新排堆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐