同时也是百度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 #include #include #include 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 v{ 1, 3, 3, 3, 1, 2, 1, 2, 6, 2, 4, 4, 4, 4 }; set s; //set用于自定义排序,自定义数据类型是因为要记录三个值 map> 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; }