一种排序STL在set中的结构体排序

第一眼看到这道题的时候 觉得就是一个sort排序 再写一个cmp嘛 后来又看到相同的要删掉 如果排序好了 再在数组中删除 那就要往前推 

那肯定非常消耗时间 那么第二个想法就是sort加上set 先排序 然后放入集合 再输出

后来一想set都已经可以按升序排列了而题目中又没有要求用降序排列的元素 那就不需要sort了 

那么在讲这道题之前先介绍一下sort的cmp

struct data
{
    int id,c,k;

}obj[10005];

bool cmp(data a,data b)
{
if(a.id!=b.id) return a.id<b.id;   //用!=能大大减少判断次数  因为!=比==出现的概率大太多 
else if(a.c!=b.c) return a.c<b.c;
else return a.k<b.k;
}
 

sort (obj,obj+n,cmp);

不知道大家有没有学sort 这里大概秒解一下吧  这小段大意是:

  如果前一个元素的id不等于后一个元素的id   return a.id<b.id 那么obj按升序排列 

那你如果写成return a.id>b.id那么obj就是按降序排列很容易懂吧 下面的c,k也是同理。

总得来说 就是先按编号id排 如果id相等 那么就按长度(c)来排 如果长度也相等 就按宽度排(k)

感兴趣的可以自己去看一下sort的源代码

其实采用的就是快速排序 需要头文件#include <algorithm>



好了 说了那么多介绍sort 但其实这道题没有用到sort 直接让结构体在集合中排好序就可以了 笔者之所以介绍 是因为接下来需要用到的和sort中的cmp非常相似

那就是函数运算符重载 大家都知道set集合是从小到大排列的 也就是升序排列 那么升序排列

其实就是< 和sort的cmp中一样

集合默认的是bool operator < (const data& a) const          这里的data 是你定义的结构体的名字

{ a是定义的结构体变量 形式参数

return a<a.id;你必须重载一下集合的升序(<)

我这个重载就是告诉集合按照id的升序进行排列
前面的a代表结构体对象 <代表按升序 a.id就是
代表需要排序的对象的元素 也就是前一个和后
一个的id的比较。


因为集合本来只针对一个对象进行升序而你用结构体造成了有多个对象 那么集合就不知道按哪个对象进行排序了 

所以需要你自己来写一个set的“cmp”也就是重载<

你如果改成return a>a.id那它就是按降序排列了

那么同理 我们可以顺藤摸瓜 这道题的结构体可以这样写:

struct data
{
    int id,c,k;
    bool operator < (const data& oDR) const
{
return id<oDR.id;
if(id!=oDR.id) return id<oDR.id; 
else if(c!=oDR.c) return c<oDR.c;
else return k<oDR.;
}
}obj[1005] ;

话不多说直接上代码 这道题最重要的是告诉我们 在set中用结构体时要重载运算符<

#include <iostream>
#include <algorithm>
#include <set>
#include <cstdlib>
#include <string.h>
using namespace std;
struct data
{
    int id,c,k;
    bool operator < (const data& oDR) const
	{
		if(id!=oDR.id) return id<oDR.id;  
		else if(c!=oDR.c) return c<oDR.c;
		else return k<oDR.k;
	}	
}obj[1005] ;
int main()
{
	set<data> result;
	int T;
	cin>>T;
	while (T--)
	{
		memset(obj,0,sizeof(obj));
		result.clear();
		int n,temp;
		cin>>n;
		for (int i = 0; i < n; i++)
		{
			cin>>obj[i].id>>obj[i].c>>obj[i].k;
			if(obj[i].c<obj[i].k) swap(obj[i].c,obj[i].k);
			result.insert(obj[i]); 
		}
		set<data>::iterator it;
		for(it = result.begin(); it != result.end(); ++it)
		{
			cout<<it->id<<" "<< it->c <<" "<<it->k<<endl;
		} 
	}
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值