数组按数字出现频次排序

题目

同时也是百度2018秋招的笔试题,LeetCode 451–根据字符出现频率排序的变形

题意为从一个乱序数组中,将其中的整数按照出现的频次多少来排列,比如输入为
[1,2,1,2,3,3,1,6,4,4,4,4],那么输出就应该为[4,4,4,4,1,1,1,2,2,3,3,6],
其中,如果某两个数字的出现频次相同,那么就按照输入用例中的原顺序排列
#include <iostream>
#include <set>
#include <map>
#include <vector>

using namespace std;
//自定义数据类型,用于记录数组中每个值,出现次数,和出现顺序(因为排序后不能影响原来顺序)
struct Data
{
	int key;                //原数组中的值
	int count;             //出现次数
	int order;             // 出现的顺序

	Data(int K, int C, int O) : key(K), count(C), order(O) {}
};
//自定义set的函数对象(伪函数),给set容器排序
struct MyComp
{
	bool operator()(const Data &d1, const Data &d2) const
	{
		if (d1.count != d2.count)       //如果次数不等,按次数高到低排序
		{
			return d1.count > d2.count;
		}
		else                                  //如果出现次数相等,按出现顺序由先到后排序
		{
			return d1.order < d2.order;
		}
	}
};


int main()
{
	vector<int> v{ 1, 3, 3, 3, 1, 2, 1, 2, 6, 2, 4, 4, 4, 4 };
	set<Data, MyComp> s;               //set用于自定义排序,自定义数据类型是因为要记录三个值
	map<int, pair<int, int>> m;           //map用于记录kv
	int order = 0;
	for (int &i : v)
	{
	/*
带有一个键-值pair形参的insert版本将返回一个值:包含一个迭代器和一个bool值得pair对象,
其中迭代器指向map中具有相应键的元素,而bool值则表示是否插入了该元素。如果该键不
在容器中,则插入新元素,且bool值为ture;如果该键已在容器中,则其关联的值保持不
变,返回bool值为false。在这两种情况下,迭代器都将指向具有给定键的元素。*/
		auto it = m.insert(make_pair(i, make_pair(1, order++)));
	if (!it.second)    //用返回的第二个对象判断是否插入成果,map中key值是唯一的,第二次会插入失败
		{
			order--;                           //插入失败则出现顺序减1
			++(it.first->second.first);           //出现次数加1
		}
	}

	for (int &i : v)     //将map值转入set,set自动排序,按照我们写的排序函数
	{
		s.insert(Data(i, m[i].first, m[i].second));
	}

	for (auto it = s.begin(); it != s.end(); ++it)      //遍历set
	{
		for (int i = 0; i < it->count; i++)
		{
			cout << it->key << " " ;
		}
	// cout << it->key << "|" << it->count << "|" << it->order << endl;
		//cout << it->key << endl; // 4 4 4 4 1 1 1 3 3 3 2 2 2 6
	}

	return 0;
}
    原文作者:Courage-Hu
    原文地址: https://blog.csdn.net/u012135009/article/details/99696346
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞