PAT A1074 Reversing Linked List 中 sort 函数的另类写法

题目链接

这道题算法笔记上面用 sort 来做,不算特别难, 但其实还可以更简单。最近在使用 min_element() 和 max_element() 函数的时候, 发现 sort 排序其实有更简单的另类写法, 并不需要定义 cmp 函数。

这道题我的第一次代码如下(按照算法笔记的思路来的):

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100010;
struct Node {
	int address, data, next;
	int order;
	Node(){
		order=maxn;
	}
}node[maxn];
bool cmp(Node a, Node b){
	return a.order<b.order;
} 
int main(){
	int begin, n ,K ,address;
	scanf("%d %d %d",&begin, &n, &K);
	for (int i=0; i<n; i++){
		scanf("%d",&address);
		scanf("%d %d",&node[address].data, &node[address].next);
		node[address].address=address;
	}
	int p=begin, count=0;
	while (p!=-1){
		node[p].order=count++;
		p=node[p].next;
	}
	sort(node, node+maxn,cmp);
	n=count;
	for (int i=0; i<n/K; i++){
		for (int j=(i+1)*K-1; j>i*K; j--){
			printf("%05d %d %05d\n",node[j].address, node[j].data, node[j-1].address);
		}
		printf("%05d %d ",node[i*K].address, node[i*K].data);
		if (i<n/K-1){
			printf("%05d\n",node[(i+2)*K-1].address);
		}else {
			if (n%K==0){
				printf("-1\n");
			}else {
				printf("%05d\n",node[(i+1)*K].address);
				for (int i=n/K *K; i<n; i++){
					printf("%05d %d ",node[i].address, node[i].data);
					if (i<n-1){
						printf("%05d\n",node[i+1].address);
					}else{
						printf("-1\n");
					}
				}
			}
		}
	}
}

非常常规 ,但是容易出错。

第二次做的代码如下(对每个元素先分组, 在赋予组内编号):

//注意几个点 比如说cnt==0 cnt==1这种极端情况 幸好本题并给有考这种极端情况
//第一次尝试在直接在结构体里面对 < 重载 , 不用写cmp 函数了, 但是g++编译器里面通过不了, clang++才行。
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=1000000000;
struct Node{
	int address;
	int data;
	int next;
	int isValid=0;
	int group=INF;
	int index;
	friend bool operator < (const Node &a, const Node &b){
		if (a.isValid!=b.isValid) return a.isValid>b.isValid;
		else if (a.group!=b.group) return a.group<b.group;
		else if (a.index!=b.index) return a.index>b.index;
	}
}node[100010];
int main(){
	int begin, n, k;
	scanf("%d %d %d", &begin, &n, &k);
	for (int i=0; i<n; i++){
		int address, data, next;
		scanf("%d %d %d",&address, &data, &next);
		node[address].address=address;
		node[address].data=data;
		node[address].next=next;
	}
	int p=begin;
	int cnt=0;
	while (p!=-1){
		node[p].isValid=1;
		node[p].group=cnt/k;
		node[p].index=cnt%k;
		cnt++;
		p=node[p].next;
	}
	sort(node, node+100010);
    n=cnt;
	if (n%k==0){
		for (int i=0; i<cnt-1; i++){
			printf("%05d %d %05d\n", node[i].address, node[i].data, node[i+1].address);
		}
		printf("%05d %d -1\n", node[cnt-1].address, node[cnt-1].data);
	}else {
		int lastCnt=n/k*k;//值得借鉴
		for (int i=0; i<lastCnt-1; i++){
			printf("%05d %d %05d\n", node[i].address, node[i].data, node[i+1].address);
		}
		printf("%05d %d %05d\n", node[lastCnt-1].address, node[lastCnt-1].data, node[cnt-1].address);
		for (int i=cnt-1; i>=lastCnt+1; i--){
			printf("%05d %d %05d\n", node[i].address, node[i].data, node[i-1].address);
		}
		printf("%05d %d -1\n", node[lastCnt].address, node[lastCnt].data);
	}
}

和第一次有啥区别呢, 主要在sort函数这一块, 我们通常是先定义一个结构体 ,然后再用cmp函数来定义如何排序, 最后用sort(a, a+n, cmp)这种形式来对结构体数组排序。

但其实可以更简单, 直接在定义结构体的时候, 在结构体内部重载 < ,定义大小规则, 这样做有很多好处:
第一, 如果遇到 set, priority_queue这些容器, 可以直接排序。
第二, 可以直接使用 min_element() 和 max_element()来找到结构体数组中想要的最值。
但是, 这种写法 评测的时候 g++ 不支持, 不过 clang++ 支持, btw, g++没有 clang++ 好用, 很多代码如果g++不行, 就换成 clang++ 试试,就能通过。(PATA 1065就是个典型例子)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值