当前位置: 首页 > news >正文

Go 排序包 sort

写在前面的使用总结:

排序结构体

实现Len,Less,Swap三个函数

package main  import (  "fmt"  "sort")  type StuScore struct {  name  string  score int  
}  type StuScores []StuScore  func (s StuScores) Len() int {  return len(s)  
}  func (s StuScores) Less(i, j int) bool {  return s[i].score < s[j].score  
}  func (s StuScores) Swap(i, j int) {  s[i], s[j] = s[j], s[i]  
}  func main() {  stus := StuScores{  {"mike ", 98},  {"jj", 91},  {"hello", 96},  {"simple", 90},  }  fmt.Println("Default:\n\t", stus)  sort.Sort(stus)  fmt.Println("IS sorted?\n\t", sort.IsSorted(stus))  fmt.Println("Sorted:\n\t", stus)  
}

排序int切片

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Ints(s)
fmt.Println(s) // 将会输出[1 2 3 4 5 6]

排序float64切片

Float := []float64{1.2, 3.4, 8.2, 1.1}  sort.Float64s(Float)  
fmt.Println(Float) //[1.1 1.2 3.4 8.2]  
fmt.Println(sort.Float64sAreSorted(Float))//true  
fmt.Println(sort.SearchFloat64s(Float, 1.2))// 1

排序string切片

Strings := []string{"1", "4", "a", "0", "2"}  sort.Strings(Strings)  
fmt.Println(Strings)  
fmt.Println(sort.StringsAreSorted(Strings))  
fmt.Println(sort.SearchStrings(Strings, "a"))  /*  
[0 1 2 4 a]  
true  
4  
*/

简介

基本实现了插入排序,归并排序,堆排序和快速排序。当然这四种排序方法是不分开的,它们是在sort包的内部被使用。所以使用时,不用考虑使用那种排序方法。
sort会自动选择合适的排序方法保证高效性。

使用:

只要实现了 sort.Interface 定义的三个方法:获取数据集合长度的 Len() 方法、比较两个元素大小的 Less() 方法和交换两个元素位置的 Swap() 方法,就可以顺利对数据集合进行排序。

数据集合排序

前面说了,对数据集合排序(包括自定义数据类型集合)排序需要实现sort.Interface接口的三个方法,我们看看该接口的定义:

type Interface interface{//获取数据集合元素个数Len() int//如果i索引的数据小于j索引的数据,返回true,且不会调用下面的Swap(),即数据升序排序Less(i,j int) bool //交换i和j索引的两个元素的位置Swap(i,j int )}

数据集合实现了这三个方法后,即可调用该包的Sort()方法进行排序,Sort()方法定义如下:

func Sort(data Interface)

Sort()方法唯一的参数就是带排序的数据集合
该包还提供了一个方法可以判断数据集合是否已经排好了顺序,该方法的内部实现依赖于我们自己实现的Len()和Less()方法:

func IsSorted(data Interface) bool {n := data.Len()for i := n - 1; i > 0; i-- {if data.Less(i, i-1) {return false}}return true
}

下面是一个使用sort包对学生成绩进行排序的实例:

package main  import (  "fmt"  "sort")  type StuScore struct {  name  string  score int  
}  type StuScores []StuScore  func (s StuScores) Len() int {  return len(s)  
}  func (s StuScores) Less(i, j int) bool {  return s[i].score < s[j].score  
}  func (s StuScores) Swap(i, j int) {  s[i], s[j] = s[j], s[i]  
}  func main() {  stus := StuScores{  {"mike ", 98},  {"jj", 91},  {"hello", 96},  {"simple", 90},  }  fmt.Println("Default:\n\t", stus)  sort.Sort(stus)  fmt.Println("IS sorted?\n\t", sort.IsSorted(stus))  fmt.Println("Sorted:\n\t", stus)  
}

该示例实现的是升序排序,如果要得到降序排序结果,其实只要修改 Less() 函数:

//Less(): 成绩降序排序 , 只将小于号修改为大于号
func (s StuScores) Less(i, j int) bool {return s[i].score > s[j].score
}

此外,sort包提供了 Reverse() 方法,可以允许将数据按 Less() 定义的排序方式逆序排序,而不必修改 Less() 代码。方法定义如下:

func Reverse(data Interface) Interface

我们可以看到 Reverse() 返回的一个 sort.Interface 接口类型,整个 Reverse() 的内部实现比较有趣:

// 定义了一个 reverse 结构类型,嵌入 Interface 接口
type reverse struct {Interface
}//reverse 结构类型的 Less() 方法拥有嵌入的 Less() 方法相反的行为
//Len() 和 Swap() 方法则会保持嵌入类型的方法行为
func (r reverse) Less(i, j int) bool {return r.Interface.Less(j, i)
}// 返回新的实现 Interface 接口的数据类型
func Reverse(data Interface) Interface {return &reverse{data}
}

了解内部原理后,可以在学生成绩排序示例中使用 Reverse() 来实现成绩升序排序:

sort.Sort(sort.Reverse(stus))
fmt.Println(stus)

最后一个方法Search()

func Search(n int,f func(int)bool) int

该方法会使用“二分查找”算法来找出能使 f(x)(0<=x<n) 返回 ture 的最小值 i。 前提条件 : f(x)(0<=x<i) 均返回 false, f(x)(i<=x<n) 均返回 ture。 如果不存在 i 可以使 f(i) 返回 ture, 则返回 n。

Search() 函数一个常用的使用方式是搜索元素 x 是否在已经升序排好的切片 s 中:

x := 11
s := []int{3, 6, 8, 11, 45} // 注意已经升序排序
pos := sort.Search(len(s), func(i int) bool { return s[i] >= x })
if pos < len(s) && s[pos] == x {fmt.Println(x, " 在 s 中的位置为:", pos)
} else {fmt.Println("s 不包含元素 ", x)
}

官方文档还给出了一个猜数字的小程序:

func GuessingGame() {var s stringfmt.Printf("Pick an integer from 0 to 100.\n")answer := sort.Search(100, func(i int) bool {fmt.Printf("Is your number <= %d? ", i)fmt.Scanf("%s", &s)return s != "" && s[0] == 'y'})fmt.Printf("Your number is %d.\n", answer)
}

sort包对于内部数据类型的排序

sort包原生支持[]int,[]float64,[]string三种内建数据类型切片的排序操作,我们不用自己实现Len(),Less(),Swap()方法

IntSlice类型及[]int排序

由于[]int切片排序内部实现及使用方法和[]float64,[]string类似,这里就描述其中一部分。

sort排序IntSlice类型,并且实现sort.Interface 接口。

type IntSlice []int
func (p IntSlice) Len() int           { return len(p) }
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p IntSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
//IntSlice 类型定义了 Sort() 方法,包装了 sort.Sort() 函数
func (p IntSlice) Sort() { Sort(p) }
//IntSlice 类型定义了 SearchInts() 方法,包装了 SearchInts() 函数
func (p IntSlice) Search(x int) int { return SearchInts(p, x) }

并且提供了sort.Ints()方法使用了该IntSlice类型:

func Ints(a []int){Sort(IntSlice(a)) } 

使用对[]int切片进行排序更常使用sort.Ints(),而不是IntSlice类型:

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Ints(s)
fmt.Println(s) // 将会输出[1 2 3 4 5 6]

如果要使用降序排序,显然要用前面提到的 Reverse() 方法:

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s) // 将会输出[6 5 4 3 2 1]

如果要查找整数 x 在切片 a 中的位置,相对于前面提到的 Search() 方法,sort包提供了 SearchInts():

func SearchInts(a []int, x int) int

注意,SearchInts() 的使用条件为:切片 a 已经升序排序 以下是一个错误使用的例子:

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据
fmt.Println(sort.SearchInts(s, 2)) // 将会输出 0 而不是 1

Float64Slice类型和[]float64排序

实现与 Ints 类似,只看一下其内部实现:

type Float64Slice []float64func (p Float64Slice) Len() int           { return len(p) }
func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j]) }
func (p Float64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p Float64Slice) Sort() { Sort(p) }
func (p Float64Slice) Search(x float64) int { return SearchFloat64s(p, x) }

与 Sort()、IsSorted()、Search() 相对应的三个方法:

func Float64s(a []float64)  
func Float64sAreSorted(a []float64) bool
func SearchFloat64s(a []float64, x float64) int

要说明一下的是,在上面 Float64Slice 类型定义的 Less 方法中,有一个内部函数 isNaN()。 isNaN() 与_math_包中 IsNaN() 实现完全相同,sort包之所以不使用 math.IsNaN(),完全是基于包依赖性的考虑,应当看到,sort包的实现不依赖与其他任何包。

StringSlice 类型及[]string 排序

两个 string 对象之间的大小比较是基于“字典序”的。

实现与 Ints 类似,只看一下其内部实现:

type StringSlice []stringfunc (p StringSlice) Len() int           { return len(p) }
func (p StringSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p StringSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p StringSlice) Sort() { Sort(p) }
func (p StringSlice) Search(x string) int { return SearchStrings(p, x) }

与 Sort()、IsSorted()、Search() 相对应的三个方法:

func Strings(a []string)
func StringsAreSorted(a []string) bool
func SearchStrings(a []string, x string) int

相关文章:

Go 排序包 sort

写在前面的使用总结&#xff1a; 排序结构体 实现Len&#xff0c;Less&#xff0c;Swap三个函数 package main import ( "fmt" "sort") type StuScore struct { name string score int } type StuScores []StuScore func (s StuScores) Len(…...

Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染

Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种&#xff1a;Java 原生发邮件mail.jar和activation.jar <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency><groupId>jav…...

CNI 网络流量分析(六)Calico 介绍与原理(二)

文章目录CNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09;CNIIPAM指定 IP指定非 IPAM IPCNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09; CNI 支持多种 datapath&#xff0c;默认是 linuxDa…...

短视频标题的几种类型和闭坑注意事项

目录 短视频标题的几种类型 1、悬念式 2、蹭热门式 3、干货式 4、对比式方法 5、总分/分总式方法 6、挑战式方式 7、启发激励式 8、讲故事式 02注意事项 1、避免使用冷门、生僻词汇 标题是点睛之笔&#xff0c;核心是视频内容 短视频标题的几种类型 1、悬念式 通过…...

操作系统——1.操作系统的概念、定义和目标

目录 1.概念 1.1 操作系统的种类 1.2电脑的组成 1.3电脑组成的介绍 1.4操作系统的概念&#xff08;定义&#xff09; 2.操作系统的功能和目标 2.1概述 2.2 操作系统作为系统资源的管理者 2.3 操作系统作为用户和计算机硬件间的接口 2.3.1用户接口的解释 2.3.2 GUI 2.3.3接…...

【html弹框拖拽和div拖拽功能】原生html页面引入vue语法后通过自定义指令简单实现div和弹框拖拽功能

前言 这是html版本的。只是引用了vue的语法。 这是很多公司会出现的一种情况&#xff0c;就是原生的页面&#xff0c;引入vue的语法开发 这就导致有些vue上很简单的功能。放到这里需要转换一下 以前写过一个vue版本的帖子&#xff0c;现在再加一个html版本的。 另一个vue版本…...

2023新华为OD机试题 - 计算网络信号(JavaScript) | 刷完必过

计算网络信号 题目 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。 注意:网络信号可以绕过阻隔物 array[m][n] 的二维数组代表网格地图,array[i][j] = 0代表 i 行 j 列是空旷位置;array[i][j] = x(x 为正整数)代表 i 行 …...

27.边缘系统的架构

文章目录27 Architecures for the Edge 边缘系统的架构27.1 The Ecosystem of Edge-Dominant Systems 边缘主导系统的生态系统27.2 Changes to the Software Development Life Cycle 软件开发生命周期的变化27.3 Implications for Architecture 对架构的影响27.4 Implications …...

机器学习强基计划8-1:图解主成分分析PCA算法(附Python实现)

目录0 写在前面1 为什么要降维&#xff1f;2 主成分分析原理3 PCA与SVD的联系4 Python实现0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xf…...

Hudi-集成Spark之spark-shell 方式

Hudi集成Spark之spark-shell 方式 启动 spark-shell &#xff08;1&#xff09;启动命令 #针对Spark 3.2 spark-shell \--conf spark.serializerorg.apache.spark.serializer.KryoSerializer \--conf spark.sql.catalog.spark_catalogorg.apache.spark.sql.hudi.catalog.Hoo…...

Python爬虫:从js逆向了解西瓜视频的下载链接的生成

前言 最近花费了几天时间,想获取西瓜视频这个平台上某个视频的下载链接,运用js逆向进行获取。其实,如果小编一开始就注意到这一点(就是在做js逆向时,打了断点之后,然后执行相关代码,查看相关变量的值,结果一下子就蹦出很多视频相关的数据,查看了网站下的相关api链接,也…...

Numpy-如何对数组进行切割

前言 本文是该专栏的第24篇,后面会持续分享python的数据分析知识,记得关注。 继上篇文章,详细介绍了使用numpy对数组进行叠加。本文再详细来介绍,使用numpy如何对数组进行切割。说句题外话,前面有重点介绍numpy的各个知识点。 感兴趣的同学,可查看笔者之前写的详细内容…...

Python之字符串精讲(下)

前言 今天继续讲解字符串下半部分&#xff0c;内容包括字符串的检索、大小写转换、去除字符串中空格和特殊字符。 一、检索字符串 在Python中&#xff0c;字符串对象提供了很多用于字符串查找的方法&#xff0c;主要给大家介绍以下几种方法。 1. count() 方法 count() 方法…...

Python图像卡通化animegan2-pytorch实例演示

先看下效果图&#xff1a; 左边是原图&#xff0c;右边是处理后的图片&#xff0c;使用的 face_paint_512_v2 模型。 项目获取&#xff1a; animegan2-pytorch 下载解压后 cmd 可进入项目地址的命令界面。 其中 img 是我自己建的&#xff0c;用于存放图片。 需要 torch 版本 …...

谢希仁版《计算机网络》期末总复习【完结】

文章目录说明第一章 计算机网络概述计算机网络和互联网网络边缘网络核心分组交换网的性能网络体系结构控制平面和数据平面第二章 IP地址分类编址子网划分无分类编址特殊用途的IP地址IP地址规划和分配第三章 应用层应用层协议原理万维网【URL / HTML / HTTP】域名系统DNS动态主机…...

问:React的useState和setState到底是同步还是异步呢?

先来思考一个老生常谈的问题&#xff0c;setState是同步还是异步? 再深入思考一下&#xff0c;useState是同步还是异步呢&#xff1f; 我们来写几个 demo 试验一下。 先看 useState 同步和异步情况下&#xff0c;连续执行两个 useState 示例 function Component() {const…...

深度理解机器学习16-门控循环单元

评估简单循环神经网络的缺点。 描述门控循环单元&#xff08;Gated Recurrent Unit&#xff0c;GRU&#xff09;的架构。 使用GRU进行情绪分析。 将GRU应用于文本生成。 基本RNN通常由输入层、输出层和几个互连的隐藏层组成。最简单的RNN有一个缺点&#xff0c;那就是它们不…...

Python中Generators教程

要想创建一个iterator&#xff0c;必须实现一个有__iter__()和__next__()方法的类&#xff0c;类要能够跟踪内部状态并且在没有元素返回的时候引发StopIteration异常. 这个过程很繁琐而且违反直觉.Generator能够解决这个问题. python generator是一个简单的创建iterator的途径…...

数据结构与算法基础-学习-10-线性表之栈的清理、销毁、压栈、弹栈

一、函数实现1、ClearSqStack&#xff08;1&#xff09;用途清理栈的空间。只需要栈顶指针和栈底指针相等&#xff0c;就说明栈已经清空&#xff0c;后续新入栈的数据可以直接覆盖&#xff0c;不用实际清理数据&#xff0c;提升了清理效率。&#xff08;2&#xff09;源码Statu…...

Leetcode 每日一题 1234. 替换子串得到平衡字符串

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

【MYSQL中级篇】数据库数据查询学习

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 相关文章 文章名文章地址【MYSQL初级篇】入门…...

华为OD机试真题JAVA实现【火星文计算】真题+解题思路+代码(20222023)

🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出描述示例一输入输出说明解题思路核心知识点Code运行结果版...

Linux基础知识

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…...

Linux 游戏性能谁的 更优秀X.Org还是Wayland!

导读X.Org 和 Wayland 是目前 Linux 平台上的两大主流显示服务器&#xff0c;那么两者在 Linux 游戏性能上谁更优秀呢&#xff1f;国外科技媒体 Phoronix 在 Ubuntu 22.10 上对其进行了多款游戏的实测。评测在运行 GNOME 43.1 的 Ubuntu 22.10 上进行测试&#xff0c;在安装英伟…...

【数据结构】算法的复杂度分析:让你拥有未卜先知的能力

&#x1f451;专栏内容&#xff1a;数据结构⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、时间复杂度1、定义2、大O的渐进表示法3、常见的时间复杂度三、空间复杂度1、定义2、常见的空间复杂度一、前…...

Linux根文件系统移植

目录 一、根文件系统 1.1根文件系统 1.2根文件系统内容 二、根文件系统移植 2.1BusyBox 2.2BusyBox的获取 2.3BusyBox的使用 2.4make menuconfig 2.5编译和安装 2.6修改根文件系统 一、根文件系统 1.1根文件系统 根文件系统是内核启动后挂载的第一个文件系统系统引…...

Three.js 无限平面快速教程【Plane】

Three.js 提供了 Plane 概念来表示在 3d 空间中无限延伸的二维表面。 这对于光标交互很有用&#xff0c;因此你可能需要了解如何设置此平面、将其可视化并根据需要进行调整。 推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 Three.js 的 Plane 文档很好而且准确&…...

在线预览PDF文件、图片,并且预览地址不显示文件或图片的真实路径。

实现在线预览PDF文件、图片&#xff0c;并且预览地址不显示文件或图片的真实路径。1、vue使用blob流在线预览PDF、图片&#xff08;包括jpg、png等格式&#xff09;。1、按钮的方法&#xff1a;2、方法详细&#xff1a;&#xff08;此方法可以在发起请求时携带token&#xff0c…...

Allegro如何设置导入Subdrawing可自由选择目录操作指导

Allegro如何设置导入Subdrawing可自由选择目录操作指导 用Allgro做PCB设计的时候,导入Subdrawing是非常常用的功能,在导入Subdrawing的时候,通常需要把Subdrawing文件放在需要导入PCB的相同目录下,不能自由选择,如下图 但是Allegro是支持自由选择目录的,只需按照下方的步…...

SpirngMVC执行原理--自学版

DispatcherServlet表示前置控制器&#xff0c;是整个SpringMVC的控制中心&#xff0c;用户发出请求&#xff0c;DispatcherServlet接收请求并拦截请求HandlerMapper为处理器映射。DispatcherServlet调用。HandlerMapping根据请求url查找HandlerHandlerExecution表示具体的Handl…...

如何注册个人网站/东莞网站优化

一.collections模块 Python拥有一些内置的数据类型&#xff0c;比如str, int, list, tuple, dict等&#xff0c; collections模块在这些内置数据类型的基础上&#xff0c;提供了几个额外的数据类型&#xff1a; namedtuple(): 生成可以使用名字来访问元素内容的tuple子类deque:…...

为wordpress安装iis rewrite 组件与配置方法/网络营销师主要做什么

访问apache官网 网址&#xff1a;https://tomcat.apache.org 在官网找到projects&#xff0c;进入 找到tomcat8&#xff0c;进入 点击zip下载&#xff0c;打开文件夹 解压到你想保存的文件夹&#xff0c;记住路径 在Tomcat文件夹中&#xff1a; bin:可执行文件 startup.bat…...

展板设计用什么软件/网站优化教程

随着深度学习技术的快速发展&#xff0c;越来越多的领域开始与之融合在一起。许多传统领域借助深度学习的赋能解决了很多之前解决不了的问题或者更好的解决了之前的一些问题。于此同时&#xff0c;成本因素也是深度学习技术在各行各业深度融合中不可忽视的因素。所以将深度学习…...

男科医院治疗一次2000元/优就业seo课程学多久

最近做以太坊钱包项目需要与前台进行json交互&#xff0c;写一个工具类&#xff0c;经普通javaBean转为json对象 1 package util;2 3 import java.lang.reflect.Field;4 import java.lang.reflect.Method;5 import java.util.List;6 7 import org.web3j.protocol.core.methods.…...

住房与城乡建设厅网站/网络软文

14、索引优化 sql优化 原因&#xff1a; 1、查询语句写的差 2、性能低&#xff0c;执行时间比较长&#xff0c;等待时间长 3、索引失效 14.1 索引 索引 index 是帮助MySQL高效获取数据的数据结构 索引是数据结构 &#xff08;树&#xff1a;B树&#xff0c;hash树等&a…...

wordpress 幻灯数据库/电商网

在写 Python 代码的时候有时候会遇到变量需要叫 type、class 的情况。但 type 是一个 Python 的 ? built-in function&#xff0c;class 是一个 keyword。 有一种解决方法是在变量后加单下划线得到 type_&#xff0c;代码里也已经有地方在用&#xff0c;符合 PEP8 的规范。参考…...