map没有随机迭代器,只有顺序迭代器,所以
不能用sort
- 默认按照
less<key>
升序排列
#include<iostream>
#include<map>
using namespace std;
int main()
{
srand((unsigned)time(NULL));
multimap<int,int>mp;
// multimap第三个参数默认为less<Key>,即 less<int>
int n;
cin>>n;
int a,b;
for(int i=0; i<n; i++)
{
a=rand()%4;
b=rand()%4;
//插入
mp.insert(pair<int,int>(a,b));
}
map<int,int>::iterator iter;
//遍历输出
for(iter=mp.begin(); iter!=mp.end(); iter++)
cout<<iter->first<<" "<<iter->second<<endl;
return 0;
}
输入8,Key升序,Value随机:
1 1
1 1
1 2
2 1
3 3
3 0
3 3
3 2
- 定义map时,用greater< Key>实现按Key值递减插入数据
multimap<int,int,greater<int> >mp;
//注意<int>后空一格
输入8,Key值降序排列,Value随机:
3 0
3 3
3 1
2 3
2 0
1 0
0 0
0 0
- 写一个函数对象1(仿函数)
#include<iostream>
#include<map>
using namespace std;
typedef struct tagIntPlus
{
int num,i;
}IntPlus;
//自定义比较规则
//注意operator是(),不是<
struct Cmp
{
bool operator () (IntPlus const &a,IntPlus const &b)const
{
if(a.num!=b.num)
return a.num<b.num;
else return a.i<b.i;
}
};
int main()
{
srand((unsigned)time(NULL));
//注意此处一定要有Cmp,否则无法排序会报错
multimap<IntPlus,int,Cmp>mp;
int n;
cin>>n;
int a,b;
IntPlus intplus;
for(int i=0; i<n; i++)
{
a=rand()%4;
b=rand()%4;
intplus.num=a;
intplus.i=b;
mp.insert(pair<IntPlus,int>(intplus,i));
}
map<IntPlus,int>::iterator iter;
for(iter=mp.begin(); iter!=mp.end(); iter++)
cout<<iter->first.num<<" "<<iter->first.i<<" "<<iter->second<<endl;
return 0;
}
输入8,
结果按Key值的num升序排列,当num值相等时按Key值的i升序排列
当Key值相等时按插入顺序排列
此时虽然表现为按Value值升序排列,但实际上只是插入的顺序巧合而已
Key.num | Key.i | i【Value】 |
---|---|---|
0 | 3 | 0 |
1 | 1 | 2 |
1 | 1 | 6 |
2 | 1 | 7 |
2 | 2 | 1 |
3 | 0 | 5 |
3 | 1 | 3 |
3 | 3 | 4 |
- 在类里重载小于号<
注意只重载小于号,不要去重载大于号
如果想改变为 升 / 降序列,只需改变判断条件即可
typedef struct tagIntPlus
{
int num,i;
bool operator < (tagIntPlus const& intplus)const
{
//当num不等时
//前一个对象的num>后一个时返回true,降序排列。
//反之升序排列
if(num!=intplus.num)
return num>intplus.num;
//当num相等时
//前一个对象的i<后一个时返回true,升序排列
else return i<intplus.i;
}
}IntPlus;
主函数只需将第一种方法中的map中的Cmp去掉即可
multimap<IntPlus,int>mp;
输入8,结果:
Key.num | Key.i | i【Value】 |
---|---|---|
0 | 2 | 0 |
0 | 1 | 1 |
0 | 1 | 5 |
0 | 0 | 2 |
2 | 2 | 4 |
3 | 3 | 3 |
3 | 2 | 6 |
3 | 1 | 7 |
再次强调不能用sort
只能将map中数据压入能用sort的容器,如vector
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>//sort
using namespace std;
typedef struct tagIntPlus
{
int num,i;
} IntPlus;
typedef pair<tagIntPlus,int> PAIR;
必须有Cmp。
虽然之后会sort,map的排序并不重要,
但是map输入数据时需要比较Key值,没有会报错
struct Cmp
{
bool operator () (IntPlus const &a,IntPlus const &b)const
{
if(a.num!=b.num)
return a.num<b.num;
else return a.i<b.i;
}
};
map会按键值Key升序排列,Value值无要求
下面才是重点:
bool cmp(PAIR const&a,PAIR const&b)
{
if(a.first.num!=b.first.num)
return a.first.num<b.first.num;
else
{
if(a.first.i!=b.first.i)
return a.first.i<b.first.i;
else return a.second>b.second;
}
}
上面需重新定义Key升序排列,否则sort之后仅按Value降序排列,Key值被打乱。
int main()
{
srand((unsigned)time(NULL));
multimap<IntPlus,int,Cmp>mp;
int n;
cin>>n;
int a,b;
IntPlus intplus;
for(int i=0; i<n; i++)
{
a=rand()%4;
b=rand()%4;
intplus.num=a;
intplus.i=b;
mp.insert(pair<IntPlus,int>(intplus,i));
}
map<IntPlus,int>::iterator iter;
cout<<"排序前:"<<endl;
for(iter=mp.begin(); iter!=mp.end(); iter++)
cout<<iter->first.num<<"|"<<iter->first.i<<"|"<<iter->second<<endl;
cout<<"排序后:"<<endl;
vector<PAIR>vec(mp.begin(),mp.end());
sort(vec.begin(),vec.end(),cmp);
int size=vec.size();
for(int i=0;i<size;i++)
cout<<vec[i].first.num<<"|"<<vec[i].first.i<<"|"<<vec[i].second<<endl;
return 0;
}
排序前:输入8,结果:
Key.num | Key.i | i【Value】 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 5 |
0 | 1 | 2 |
0 | 1 | 7 |
0 | 2 | 3 |
1 | 3 | 4 |
2 | 0 | 1 |
3 | 3 | 6 |
排序后:
key肯定都没变,Vaule 如愿降序!
Key.num | Key.i | i【Value】 |
---|---|---|
0 | 0 | 5 |
0 | 0 | 0 |
0 | 1 | 7 |
0 | 1 | 2 |
0 | 2 | 3 |
1 | 3 | 4 |
2 | 0 | 1 |
3 | 3 | 6 |
完结撒花★,°:.☆( ̄▽ ̄)/$:.°★ 。
函数对象:即调用操作符的类,其对象常称为函数对象(function object),它们是行为类似函数的对象。表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个 类,其实质是对operator()操作符的重载。 ↩︎