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

go语言接口之sort.Interface接口

        排序操作和字符串格式化一样是很多程序经常使用的操作。尽管一个最短的快排程序只要15 行就可以搞定,但是一个健壮的实现需要更多的代码,并且我们不希望每次我们需要的时候 都重写或者拷贝这些代码。

        幸运的是,sort包内置的提供了根据一些排序函数来对任何序列排序的功能。它的设计非常独 到。在很多语言中,排序算法都是和序列数据类型关联,同时排序函数和具体类型元素关 联。相比之下,Go语言的sort.Sort函数不会对具体的序列和它的元素做任何假设。相反,它 使用了一个接口类型sort.Interface来指定通用的排序算法和可能被排序到的序列类型之间的约 定。这个接口的实现由序列的具体表示和它希望排序的元素决定,序列的表示经常是一个切 片。

        一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换 两个元素的方式;这就是sort.Interface的三个方法:

package sorttype Interface interface {Len() intLess(i, j int) bool // i, j are indices of sequence elementsSwap(i, j int)
}

         为了对序列进行排序,我们需要定义一个实现了这三个方法的类型,然后对这个类型的一个 实例应用sort.Sort函数。思考对一个字符串切片进行排序,这可能是最简单的例子了。下面是 这个新的类型StringSlice和它的Len,Less和Swap方法

type StringSlice []string
func (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] }

        现在我们可以通过像下面这样将一个切片转换为一个StringSlice类型来进行排序:

sort.Sort(StringSlice(names))

        这个转换得到一个相同长度,容量,和基于names数组的切片值;并且这个切片值的类型有 三个排序需要的方法。

        对字符串切片的排序是很常用的需要,所以sort包提供了StringSlice类型,也提供了Strings函 数能让上面这些调用简化成sort.Strings(names)。

        这里用到的技术很容易适用到其它排序序列中,例如我们可以忽略大些或者含有特殊的字 符。(本书使用Go程序对索引词和页码进行排序也用到了这个技术,对罗马数字做了额外逻 辑处理。)对于更复杂的排序,我们使用相同的方法,但是会用更复杂的数据结构和更复杂 地实现sort.Interface的方法。

        我们会运行上面的例子来对一个表格中的音乐播放列表进行排序。每个track都是单独的一 行,每一列都是这个track的属性像艺术家,标题,和运行时间。想象一个图形用户界面来呈 现这个表格,并且点击一个属性的顶部会使这个列表按照这个属性进行排序;再一次点击相 同属性的顶部会进行逆向排序。让我们看下每个点击会发生什么响应。

        下面的变量tracks包好了一个播放列表。(One of the authors apologizes for the other author’s musical tastes.)每个元素都不是Track本身而是指向它的指针。尽管我们在下面的代 码中直接存储Tracks也可以工作,sort函数会交换很多对元素,所以如果每个元素都是指针会 更快而不是全部Track类型,指针是一个机器字码长度而Track类型可能是八个或更多。

type Track struct {Title stringArtist stringAlbum stringYear intLength time.Duration
}var tracks = []*Track{{"Go", "Delilah", "From the Roots Up", 2012, length("3m38s")},{"Go", "Moby", "Moby", 1992, length("3m37s")},{"Go Ahead", "Alicia Keys", "As I Am", 2007, length("4m36s")},{"Ready 2 Go", "Martin Solveig", "Smash", 2011, length("4m24s")},
}func length(s string) time.Duration {d, err := time.ParseDuration(s)if err != nil {panic(s)}return d
}

         printTracks函数将播放列表打印成一个表格。一个图形化的展示可能会更好点,但是这个小程 序使用text/tabwriter包来生成一个列是整齐对齐和隔开的表格,像下面展示的这样。注意到 *tabwriter.Writer是满足io.Writer接口的。它会收集每一片写向它的数据;它的Flush方法会格 式化整个表格并且将它写向os.Stdout(标准输出)。

func printTracks(tracks []*Track) {const format = "%v\t%v\t%v\t%v\t%v\t\n"tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)fmt.Fprintf(tw, format, "Title", "Artist", "Album", "Year", "Length")fmt.Fprintf(tw, format, "-----", "------", "-----", "----", "------")for _, t := range tracks {fmt.Fprintf(tw, format, t.Title, t.Artist, t.Album, t.Year, t.Length)}tw.Flush() // calculate column widths and print table
}

        为了能按照Artist字段对播放列表进行排序,我们会像对StringSlice那样定义一个新的带有必 须Len,Less和Swap方法的切片类型。

type byArtist []*Track
func (x byArtist) Len() int { return len(x) }
func (x byArtist) Less(i, j int) bool { return x[i].Artist < x[j].Artist }
func (x byArtist) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

        为了调用通用的排序程序,我们必须先将tracks转换为新的byArtist类型,它定义了具体的排 序:

sort.Sort(byArtist(tracks))

        在按照artist对这个切片进行排序后,printTrack的输出如下

Title Artist Album Year Length
----- ------ ----- ---- ------
Go Ahead Alicia Keys As I Am 2007 4m36s
Go Delilah From the Roots Up 2012 3m38s
Ready 2 Go Martin Solveig Smash 2011 4m24s
Go Moby Moby 1992 3m37s

        对于我们需要的每个切片元素类型和每个排序函数,我们需要定义一个新的sort.Interface实 现。如你所见,Len和Swap方法对于所有的切片类型都有相同的定义。下个例子,具体的类 型customSort会将一个切片和函数结合,使我们只需要写比较函数就可以定义一个新的排 Go语言圣经 sort.Interface接口 252 序。顺便说下,实现了sort.Interface的具体类型不一定是切片类型;customSort是一个结构体类型。

type customSort struct {t []*Trackless func(x, y *Track) bool
}
func (x customSort) Len() int
func (x customSort) Less(i, j int) bool { return x.less(x.t[i], x.t[j]) }
func (x customSort) Swap(i, j int) { x.t[i], x.t[j] = x.t[j], x.t[i] }

        让我们定义一个多层的排序函数,它主要的排序键是标题,第二个键是年,第三个键是运行 时间Length。下面是该排序的调用,其中这个排序使用了匿名排序函数:

sort.Sort(customSort{tracks, func(x, y *Track) bool {if x.Title != y.Title {return x.Title < y.Title}if x.Year != y.Year {return x.Year < y.Year}if x.Length != y.Length {return x.Length < y.Length}return false
}})

        这下面是排序的结果。注意到两个标题是“Go”的track按照标题排序是相同的顺序,但是在按 照year排序上更久的那个track优先。

Title Artist Album Year Length
----- ------ ----- ---- ------
Go Moby Moby 1992 3m37s
Go Delilah From the Roots Up 2012 3m38s
Go Ahead Alicia Keys As I Am 2007 4m36s
Ready 2 Go Martin Solveig Smash 2011 4m24s

        尽管对长度为n的序列排序需要 O(n log n)次比较操作,检查一个序列是否已经有序至少需要n −1次比较。sort包中的IsSorted函数帮我们做这样的检查。像sort.Sort一样,它也使用 sort.Interface对这个序列和它的排序函数进行抽象,但是它从不会调用Swap方法:这段代码 示范了IntsAreSorted和Ints函数和IntSlice类型的使用:

values := []int{3, 1, 4, 1}
fmt.Println(sort.IntsAreSorted(values)) // "false"
sort.Ints(values)
fmt.Println(values) // "[1 1 3 4]"
fmt.Println(sort.IntsAreSorted(values)) // "true"
sort.Sort(sort.Reverse(sort.IntSlice(values)))
fmt.Println(values) // "[4 3 1 1]"
fmt.Println(sort.IntsAreSorted(values)) // "false"

        为了使用方便,sort包为[]int,[]string和[]float64的正常排序提供了特定版本的函数和类型。对 于其他类型,例如[]int64或者[]uint,尽管路径也很简单,还是依赖我们自己实现。

相关文章:

go语言接口之sort.Interface接口

排序操作和字符串格式化一样是很多程序经常使用的操作。尽管一个最短的快排程序只要15 行就可以搞定&#xff0c;但是一个健壮的实现需要更多的代码&#xff0c;并且我们不希望每次我们需要的时候 都重写或者拷贝这些代码。 幸运的是&#xff0c;sort包内置的提供了根据一些排序…...

android:text 总为大写字母的原因

当设置某个 Button 的 text 为英文时&#xff0c;界面上显示的是该英文的大写形式&#xff08;uppercase&#xff09;。例如&#xff1a; <Buttonandroid:id"id/btn"android:layout_width"wrap_content"android:layout_height"wrap_content"…...

CISCN2024 初赛 wp 部分复现(Re)

Misc 1. 火锅链观光打卡 答题即可 Re 1. asm_re 感谢智谱清言&#xff0c;可以读出大致加密算法 这是输入 这是加密部分 这里判断 找到疑似密文的部分&#xff0c;手动改一下端序 #asm_wp def dec(char):return (((char - 0x1E) ^ 0x4D) - 0x14) // 0x50 #return (ord(cha…...

YOLOv10、YOLOv9 和 YOLOv8 在实际视频中的对比

引言 目标检测技术是计算机视觉领域的核心任务之一&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列模型凭借其高效的检测速度和准确率成为了业界的宠儿。本文将详细对比YOLOv10、YOLOv9和YOLOv8在实际视频中的表现&#xff0c;探讨它们在性能、速度和实际应用…...

热题系列章节5

169. 多数元素 给定一个大小为 n 的数组&#xff0c;找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1: 输入: [3,2,3] 输出: 3 示例 2: 输入: [2,2,1,1,1,2,2] 输出:…...

ArcGIS for js 4.x 加载图层

二维&#xff1a; 1、创建vue项目 npm create vitelatest 2、安装ArcGIS JS API依赖包 npm install arcgis/core 3、引入ArcGIS API for JavaScript模块 <script setup> import "arcgis/core/assets/esri/themes/light/main.css"; import Map from arcgis…...

Three.js和Babylon.js,webGL中的对比效果分析!

hello&#xff0c;今天分享一些three.js和babylon.js常识&#xff0c;为大家选择three.js还是babylon.js做个分析&#xff0c;欢迎点赞评论转发。 一、Babylon.js是什么 Babylon.js是一个基于WebGL技术的开源3D游戏引擎和渲染引擎。它提供了一套简单易用的API&#xff0c;使开发…...

flask实现抽奖程序(一)

后端代码E:\LearningProject\lottery\app.py from flask import Flask, render_template import randomapp Flask(__name__)employees [赵一, 钱二, 孙三, 李四, 周五, 吴六, 郑七, 王八]app.route(/) def hello_world():return render_template(index.html, employeesemplo…...

Python中数据库连接的管理

在现代应用程序中&#xff0c;数据库是一个至关重要的组件。无论是小型应用还是大型分布式系统&#xff0c;良好的数据库连接管理都是确保系统高效、可靠运行的关键。本文将详细介绍在Python中管理数据库连接的最佳实践和技术&#xff0c;包括连接池、ORM&#xff08;对象关系映…...

【JAVA技术】mybatis 数据库敏感字段加解密方案

引言&#xff1a;自从有公司项目前2年做了三级等保&#xff0c;每年一度例行公事&#xff0c;昨天继续配合做等保测试。这2天比较忙&#xff0c;这里整理之前写的一篇等保技术文章。 正文&#xff1a; 现在公司项目基本用mybatis实现&#xff0c;但由于项目跨度年份比较久&…...

Collections工具类及其案例

package exercise;public class Demo1 {public static void main(String[] args) {//可变参数//方法形参的个数是可以发生变化的//格式&#xff1a;属性类型...名字//int...argsint sum getSum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);System.out.println(sum);}//底层&#xff1a;可…...

Duck Bro的第512天创作纪念日

Tips&#xff1a;发布的文章将会展示至 里程碑专区 &#xff0c;也可以在 专区 内查看其他创作者的纪念日文章 我的创作纪念日第512天 文章目录 我的创作纪念日第512天一、与CSDN平台的相遇1. 为什么在CSDN这个平台进行创作&#xff1f;2. 创作这些文章是为了赚钱吗&#xff1f…...

【机器学习】GPT-4中的机器学习如何塑造人类与AI的新对话

&#x1f680;时空传送门 &#x1f50d;引言&#x1f4d5;GPT-4概述&#x1f339;机器学习在GPT-4中的应用&#x1f686;文本生成与摘要&#x1f388;文献综述与知识图谱构建&#x1f6b2;情感分析与文本分类&#x1f680;搜索引擎优化&#x1f4b4;智能客服与虚拟助手&#x1…...

晨控CK-UR12-E01与欧姆龙NX/NJ系列EtherNet/IP通讯手册

晨控CK-UR12-E01与欧姆龙NX/NJ系列EtherNet/IP通讯手册 晨控CK-UR12-E01 是天线一体式超高频读写器头&#xff0c;工作频率默认为902MHz&#xff5e;928MHz&#xff0c;符合EPC Global Class l Gen 2&#xff0f;IS0-18000-6C 标准&#xff0c;最大输出功率 33dBm。读卡器同时…...

模板显式、隐式实例化和(偏)特化、具体化的详细分析

最近看了<The C Programing Language>看到了模板的特化&#xff0c;突然想起来<C Primer>上说的显式具体化、隐式具体化、特化、偏特化、具体化等概念弄得头晕脑胀&#xff0c;我在网上了找了好多帖子&#xff0c;才把概念给理清楚。 看着这么多叫法&#xff0c;其…...

软件设计师笔记-计算机系统基础知识

CPU的功能 CPU(中央处理器)是计算机的核心部件,负责执行计算机的指令和处理数据。它的功能主要可以分为程序控制、操作控制、时间控制和数据处理四个方面: 程序控制:CPU的首要任务是执行存储在内存中的程序。程序控制功能确保CPU能够按照程序的指令序列,一条一条地执行。…...

flink 作业动态维护更新,不重启flink,不提交作业

Flink任务实时获取并更新规则_flink任务流实时变更-CSDN博客 一种动态更新flink任务配置的方法_flink 数据源 动态更新-CSDN博客 Flink CEP在实时风控场景的落地与优化 最佳实践 - 在SQL任务中使用Flink CEP - 《实时计算用户手册-v4.5.0》 Flink SQL CEP详解-CSDN博客 如…...

为何数据仓库需要“分层次”?

在数据驱动的商业世界中&#xff0c;数据仓库是企业决策的心脏。然而&#xff0c;一个高效、可扩展且易于管理的数据仓库&#xff0c;需要精心设计和构建。分层是构建数据仓库的关键策略之一。本文将探讨数据仓库分层的重要性以及它如何帮助企业更好地管理数据。 数据仓库分层…...

小熊家务帮day15-day18 预约下单模块(预约下单,熔断降级,支付功能,退款功能)

目录 1 预约下单1.1 需求分析1.1.1 业务流程1.1.2 订单状态 1.2 系统设计1.2.1 订单表设计1.2.2 表结构的设置 1.3 开发远程调用接口1.3.0 复习下远程调用的开发1.3.1 查询地址簿远程接口jzo2o-api工程定义接口Customer服务实现接口 1.3.2 查询服务&服务项远程接口jzo2o-ap…...

[word] word悬挂缩进怎么设置? #经验分享#职场发展#经验分享

word悬挂缩进怎么设置&#xff1f; 在编辑Word的时候上方会有个Word标尺&#xff0c;相信很多伙伴都没使用过。其实它隐藏着很多好用的功能&#xff0c;今天就给大家分享下利用这个word标尺的悬挂缩进怎么设置&#xff0c;一起来看看吧&#xff01; 1、悬挂缩进 选中全文&…...

6-Maven的使用

6-Maven的使用 常用maven命令 //常用maven命令 mvn -v //查看版本 mvn archetype:create //创建 Maven 项目 mvn compile //编译源代码 mvn test-compile //编译测试代码 mvn test //运行应用程序中的单元测试 mvn site //生成项目相关信息的网站 mvn package //依据项目生成 …...

WPF真入门教程32--WPF数字大屏项目实干

1、项目背景 WPF (Windows Presentation Foundation) 是微软的一个框架&#xff0c;用于构建桌面客户端应用程序&#xff0c;它支持富互联网应用程序&#xff08;RIA&#xff09;的开发。在数字大屏应用中&#xff0c;WPF可以用来构建复杂的用户界面&#xff0c;展示庞大的数据…...

数据可视化Python实现超详解【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…...

Maxkb玩转大语言模型

Maxkb玩转大语言模型 随着国外大语言模型llama3的发布&#xff0c;搭建本地个人免费“人工智能”变得越来越简单&#xff0c;今天博主分享使用Max搭建本地的个人聊天式对话及个人本地知识域的搭建。 1.安装Maxkb开源应用 github docker快速安装 docker run -d --namemaxkb -p 8…...

React Hooks 封装可粘贴图片的输入框组件(wangeditor)

需求是需要一个文本框 但是可以支持右键或者ctrlv粘贴图片&#xff0c;原生js很麻烦&#xff0c;那不如用插件来实现吧~我这里用的wangeditor插件&#xff0c;初次写初次用&#xff0c;可能不太好&#xff0c;但目前是可以达到实现需求的一个效果啦&#xff01;后面再改进吧~ …...

Wireshark TS | 应用传输丢包问题

问题背景 仍然是来自于朋友分享的一个案例&#xff0c;实际案例不难&#xff0c;原因也就是互联网线路丢包产生的重传问题。但从一开始只看到数据包截图的判断结果&#xff0c;和最后拿到实际数据包的分析结果&#xff0c;却不是一个结论&#xff0c;方向有点跑偏&#xff0c;…...

架构设计-web项目中跨域问题涉及到的后端和前端配置

WEB软件项目中经常会遇到跨域问题&#xff0c;解决方案早已是业内的共识&#xff0c;简要记录主流的处理方式&#xff1a; 跨域感知session需要解决两个问题&#xff1a; 1. 跨域问题 2. 跨域cookie传输问题 跨域问题 解决跨域问题有很多种方式&#xff0c;如使用springboot…...

==Redis淘汰策略(内存满了触发)==

好的&#xff0c;面试官。这个问题我需要从三个方面来回答。第一个方面&#xff1a; 当 Redis 使用的内存达到 maxmemory 参数配置的阈值的时候&#xff0c;Redis 就会根据配置的内存淘汰策略。 把访问频率不高的 key 从内存中移除。maxmemory 默认情况是当前服务器的最大内存…...

2024年高考作文考人工智能,人工智能写作文能否得高分

前言 众所周知&#xff0c;今年全国一卷考的是人工智能&#xff0c;那么&#xff0c;我们来测试一下&#xff0c;国内几家厉害的人工智能他们的作答情况&#xff0c;以及能取得多少高分呢。由于篇幅有限&#xff0c;我这里只测试一个高考真题&#xff0c;我们这里用百度的文心…...

Vue3学习记录第三天

Vue3学习记录第三天 背景说明学习记录Vue3中shallowReactive()和shallowRef()Vue3中toRaw()和markRaw()前端...语法Vue3中readonly()和shallowReadonly()函数前端的防抖 背景 之前把Vue2的基础学了, 这个课程的后面有简单介绍Vue3的部分. 学习知识容易忘, 这里仅简答做一个记录…...

电商平台开网店/东莞做网站优化

2019独角兽企业重金招聘Python工程师标准>>> win7程序报错&#xff0c;提示out of memory(Physical) 解决办法&#xff1a; 打开开始菜单&#xff0c;在搜索栏里面输入CMD&#xff0c;在查找到结果中找到CMD.exe&#xff0c; 按右键以管理员身份运行。在弹出的黑色命…...

icp备案查询网站/推广一款app的营销方案

图形函数库&#xff1a;#include <graphics.h> 图形模式的初始化和关闭 ① 显示器有两种显示模式&#xff1a; 文本模式&#xff1a;默认模式&#xff0c;只能显示文本&#xff0c;图形函数不能工作。 图形模式&#xff1a;图形函数可以工作&…...

漯河市建设局网站/外链seo服务

最近忙于一个RF产品的量产程序开发&#xff0c;测试平台选用advantest V93K SMT8,使用WSRF板卡&#xff08;最高支持6Gbps&#xff09;做LTE RX/TX的RF测试。大部分RF测试项都是大家耳熟能详的&#xff0c;比如RX/TX gain&#xff0c;LO IPN&#xff0c;RX flatness&#xff0c…...

网站开发开什么票/培训网址

http://www.elecfans.com/tongxin/123/20180103610476.html 经常看到RS485和MODBUS写在一起&#xff0c;它们的区别和联系&#xff1f; RS485是一个物理接口&#xff0c;简单的说是硬件。 MODBUS是一种国际标准的通讯协议&#xff0c;用于不同厂商之间的设备交换数据&#xff0…...

做网站能创业吗/怎样做一个自己的网站

这是17年暑假学习Linux汇编语言的笔记记录&#xff0c;参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译《汇编语言基于Linux环境》的书&#xff0c;喜欢看原版书的同学可以看《Assembly Language Step-By-Setp:Programming with Linux 3rd Edition》&#xff0c;非常感谢该…...

如何做公司企业网站/网站域名查询ip

static &#xff08;静态修饰符&#xff09; 1.用来修饰成员变量 成员变量被static修饰 就叫静态成员变量&#xff0c;如果没有修饰叫非静态成员变量。 静态成员变量的访问方式&#xff1a; 1.用对象进行访问&#xff0c;直接点语法拿到。如&#xff1a;对象名.变量名 2.通过类…...