首页 > 其他分享 >使用lambda表达式实现sort的自定义排序

使用lambda表达式实现sort的自定义排序

时间:2023-01-02 22:23:07浏览次数:52  
标签:sort return 自定义 int Java 表达式 lambda

使用lambda表达式实现sort的自定义排序(C++ and Java)

首先大致讲一下什么是lambda表达式

你也可以将它就当做是匿名函数,lambda表达式其实就是匿名函数演化出的一种语法系统

举个栗子:

普通函数

int function(int x, int y);   //声明(定义)
function(1, 2);              //调用

匿名函数(lambda表达式)

[](int x, int y){函数主体};          //声明(定义)
[](int x, int y){函数主体}(1, 2);    //调用

一个很明显的区别就是使用lambda表达式就省去了给函数命名的工作

而且对于一些简短的函数,直接用lambda表达式声明+调用能提高一点编码效率

就比如说,常用的自定义sort的比较函数


关于lambda表达式如果想进一步了解:

使用Java的同学可以再读读廖老师这篇教程 -> 传送门

使用C++的同学可以读读这篇博客 -> 传送门


如果我们用普通函数的写法来重载运算符
那么是这样写
(想了解更多,可以读读我的这篇文章 -> 传送门)

正文开始

C++篇

#include<bits/stdc++.h>
using namespace std;
int a[15]={0,10,9,8,1,5,2,3,6,4,7};
bool cmp(int x,int y){return x>y;}
//这样实现的是降序
//C++内部默认用的是<实现sort,所以是升序
//比较函数的意义就在于将<重载为> 
int main()
{
	sort(a, a+11, cmp);
	for(int i=0;i<=10;i++)
	cout<<a[i]<<" ";
	return 0;
}

而用lambda表达式就可以这样写

#include<bits/stdc++.h>
using namespace std;
int a[15]={0,10,9,8,1,5,2,3,6,4,7};
int main()
{
	sort(a,a+11,[](int x,int y){return x>y;});
	for(int i=0;i<=10;i++)
	cout<<a[i]<<" ";
	return 0;
}

同样lambda表达式对vector也是适用的

#include<bits/stdc++.h>
using namespace std;
int a[15]={0,10,9,8,1,5,2,3,6,4,7};
int main()
{
	vector<int> b;
	for(auto x : a) //把a数组复制给b向量 
		b.push_back(x);
	sort(b.begin(),b.end(),[](int x,int y){return x>y;} );
	for(int i=0;i<=10;i++)
	cout<<b[i]<<" ";
	return 0;
}

大多数情况下,我们可能是针对pair或结构体来自定义比较函数
那么修改对应数据类型(结构体名)就ok了,类似这样:

#include<bits/stdc++.h>
using namespace std;
int a[15]={0,10,9,8,1,5,2,3,6,4,7};
typedef pair<int, int> pii;
int main()
{
	vector<pii> b;
	for(auto x : a) //把a数组复制给b向量 
		b.push_back(make_pair(x,x+1));
	sort(b.begin(),b.end(),[](pii x,pii y){return x.first>y.first;} );
	for(int i=0;i<=10;i++)
	cout<<b[i].second<<" ";
	return 0;
}

补充一点

sort(b.begin(),b.end(),[](int x,int y){return x>y;} );

原本应该是这样的,

sort(b.begin(),b.end(),[](int x,int y) -> bool {return x>y;} );

不过C++可以自动识别函数返回值得数据类型,所以可以简写。

Java篇

//实现对a数组的降序排序
import java.util.*;
public class Main 
{
    public static void main(String[] args) 
	{
        Scanner sc = new Scanner(System.in);
        Integer[] a = {0,10,9,8,1,5,2,3,6,4,7};
        Arrays.sort(a, (x,y) -> {
        	return y-x;//此处实现的是降序
        });
        for (int i = 0; i < a.length; i++) 
		{
			System.out.printf("%d ",a[i]);
		}
    }
}

Java的sort比较机制不同与C++

如果要实现降序就是后-前

升序就是前-后

此外,这样写也能实现降序(用内置compareTo函数)

 Arrays.sort(a, (x,y) -> {
        	return y.compareTo(x);//此处实现的是降序
        });

反之,return x.compareTo(y); 就是升序

因为只有一行语句,所以可以更简洁美观一点,直接省略花括号

 Arrays.sort(a, (x,y) -> y-x;);

结构体方面,感觉java用起来没有C++舒服

我们就通过这道经典的[NOIP2007 普及组] 奖学金演示一遍Java的写法吧

做这道题需要用到Java的类与接口

朴素做法就是通过自定义一个class从而自定义compareTo来做

import java.util.*;
public class Main 
{
	public static void main(String[] args) 
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		Student[] stu = new Student[n+5];
		for(int i=1; i<=n; i++)
		{
			int c = sc.nextInt();
			int m = sc.nextInt();
			int e = sc.nextInt();
			stu[i] = new Student(i, c, m, e, c+m+e);
		}
		Arrays.sort(stu, 1, n+1);
		for(int i=1; i<=5; i++)
			System.out.println(stu[i].id+" "+stu[i].tot);
	}
}
class Student implements Comparable<Student> 
{
	int c,m,e,id;//语数英、学号
	int tot;//总分
	public Student(int id,int c,int m,int e,int tot) 
	{
		this.id=id;
		this.c=c;
		this.m=m;
		this.e=e;
		this.tot=tot;
	}
	public int compareTo(Student st) 
	{
		if(this.tot != st.tot) return st.tot-this.tot;
		//因为是降序,所以是To后的那个数减前面的数
		if(this.c != st.c) return st.c-this.c;
		return this.id-st.id;//此处是升序
	}
}

不过Java和C++的一个不同点是,
Java没有结构体
而Java里定义一个类本身也就要求必须有compareTo
所以在本题中的这个Student类就没法自定义匿名比较函数

当然这道题想用lambda表达式来简化代码,也是可以的

因为Java里的数组也是对象,所以我们也可以对一个二维数组中进行sort

而lambda表达式也是可以针对数组对象的

import java.util.*;
public class Main
{
    public static void main(String[] args) 
    {
    	Scanner sc = new Scanner(System.in);
    	int n = sc.nextInt();
    	int[][] a = new int[n+5][6];
    	for(int i=1; i<=n; i++)
    	{
    		a[i][1] = i;
    		for(int j=2; j<=4; j++)
    		{
    			a[i][j] = sc.nextInt();
    			a[i][5] += a[i][j];
    		}
    	}
    	Arrays.sort(a, 1, 1+n, (x,y)->{
    		if(x[5] != y[5]) return y[5]-x[5];
    		if(x[2] != y[2]) return y[2]-x[2];
    		return x[1]-y[1];
    	});
    	for(int i=1; i<=5; i++)
    		System.out.println(a[i][1]+" "+a[i][5]);
    }
}

这样写,代码就简化很多了

标签:sort,return,自定义,int,Java,表达式,lambda
From: https://www.cnblogs.com/zhouzhihao/p/17018126.html

相关文章

  • Excel 自定义格式
    Excel自定义格式代码的结构,常规情况下分为四部分,中间用英文的分号;分隔,每一段的意思是:正数格式;负数格式;零格式;文本格式如果使用条件判断,每一段的意思是:[条件1]指定......
  • 一步一步自定义SpringMVC参数解析器
    ​​​​随心所欲,自定义参数解析器绑定数据。题图:fromZoommy干货SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上。自定义一个参数解析器需要实现......
  • odoo10如何自定义自动生成单据编号
    1.在已有的model中穿件一个字段nameclassqingjiadan(models.Model):_name='qingjia.qingjiadan'name=fields.Char(string='编号',readonly=True)2.创建qingjia_app......
  • [C/C++] C++之Lambda表达式
    Lambda表达式也叫匿名函数,有时候也叫闭包(Closure)参考视频:注意视频中捕获变量部分有错误,按本博客为准1.定义[OuterVar](intx,inty)->int{returnOuterVar+......
  • jsp自定义标签
    jsp自定义标签   需求:向浏览器输出当前客户的IP地址(只能使用jsp标签)1.自定义标签开发步骤    1. 编写一个普通的java类,继承SimpleTagSupport......
  • Django自定义分页器
    目录Django自定义分页器一、分页器思路二、自定义分页器的使用Django自定义分页器一、分页器思路分页器主要听处理逻辑代码最后很简单推导流程 1.queryset支持切片......
  • Arrays.sort() in Java with examples
    https://www.geeksforgeeks.org/arrays-sort-in-java-with-examples/Arrayclass isaclasscontainingstaticmethodsthatareusedwitharraysinordertosearch......
  • WPF 自定义附加事件
    我们都知道路由事件,而附加路由事件用的比较少。但如果是通用的场景,类似附加属性,附加事件就很有必要的。举个例子,输有这么多输入事件Mouse、Touch、Stylus,另外按钮Click还处......
  • 自定义注解
    记录一点关于自定义注解的小事儿记录一些遇到过的问题“Cannotfindmethod'value'”定义了一个自定义注解,@Target({ElementType.FIELD})@Retention(RetentionPolicy......
  • sortedArrDistanceLessK() 已知一个几乎有序的数组。几乎有序是指,如果把数组排好顺序
    packageclass06;importjava.util.Arrays;importjava.util.PriorityQueue;/***sortedArrDistanceLessK()*已知一个几乎有序的数组。几乎有序是指,如果把数组......