mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-11-17 17:12:59 +00:00
第7章,部分字词修订,语序调整。少量错误修订。
This commit is contained in:
@@ -34,11 +34,11 @@ sort.Sort(StringSlice(names))
|
||||
|
||||
对字符串切片的排序是很常用的需要,所以sort包提供了StringSlice类型,也提供了Strings函数能让上面这些调用简化成sort.Strings(names)。
|
||||
|
||||
这里用到的技术很容易适用到其它排序序列中,例如我们可以忽略大些或者含有特殊的字符。(本书使用Go程序对索引词和页码进行排序也用到了这个技术,对罗马数字做了额外逻辑处理。)对于更复杂的排序,我们使用相同的方法,但是会用更复杂的数据结构和更复杂地实现sort.Interface的方法。
|
||||
这里用到的技术很容易适用到其它排序序列中,例如我们可以忽略大小写或者含有的特殊字符。(本书使用Go程序对索引词和页码进行排序也用到了这个技术,对罗马数字做了额外逻辑处理。)对于更复杂的排序,我们使用相同的方法,但是会用更复杂的数据结构和更复杂地实现sort.Interface的方法。
|
||||
|
||||
我们会运行上面的例子来对一个表格中的音乐播放列表进行排序。每个track都是单独的一行,每一列都是这个track的属性像艺术家,标题,和运行时间。想象一个图形用户界面来呈现这个表格,并且点击一个属性的顶部会使这个列表按照这个属性进行排序;再一次点击相同属性的顶部会进行逆向排序。让我们看下每个点击会发生什么响应。
|
||||
|
||||
下面的变量tracks包好了一个播放列表。(One of the authors apologizes for the other author’s musical tastes.)每个元素都不是Track本身而是指向它的指针。尽管我们在下面的代码中直接存储Tracks也可以工作,sort函数会交换很多对元素,所以如果每个元素都是指针会更快而不是全部Track类型,指针是一个机器字码长度而Track类型可能是八个或更多。
|
||||
下面的变量tracks包含了一个播放列表。(One of the authors apologizes for the other author’s musical tastes.)每个元素都不是Track本身而是指向它的指针。尽管我们在下面的代码中直接存储Tracks也可以工作,sort函数会交换很多对元素,所以如果每个元素都是指针而不是Track类型会更快,指针是一个机器字码长度而Track类型可能是八个或更多。
|
||||
|
||||
<u><i>gopl.io/ch7/sorting</i></u>
|
||||
```go
|
||||
@@ -66,7 +66,7 @@ func length(s string) time.Duration {
|
||||
}
|
||||
```
|
||||
|
||||
printTracks函数将播放列表打印成一个表格。一个图形化的展示可能会更好点,但是这个小程序使用text/tabwriter包来生成一个列是整齐对齐和隔开的表格,像下面展示的这样。注意到`*tabwriter.Writer`是满足io.Writer接口的。它会收集每一片写向它的数据;它的Flush方法会格式化整个表格并且将它写向os.Stdout(标准输出)。
|
||||
printTracks函数将播放列表打印成一个表格。一个图形化的展示可能会更好点,但是这个小程序使用text/tabwriter包来生成一个列整齐对齐和隔开的表格,像下面展示的这样。注意到`*tabwriter.Writer`是满足io.Writer接口的。它会收集每一片写向它的数据;它的Flush方法会格式化整个表格并且将它写向os.Stdout(标准输出)。
|
||||
|
||||
```go
|
||||
func printTracks(tracks []*Track) {
|
||||
@@ -81,7 +81,7 @@ func printTracks(tracks []*Track) {
|
||||
}
|
||||
```
|
||||
|
||||
为了能按照Artist字段对播放列表进行排序,我们会像对StringSlice那样定义一个新的带有必须Len,Less和Swap方法的切片类型。
|
||||
为了能按照Artist字段对播放列表进行排序,我们会像对StringSlice那样定义一个新的带有必须的Len,Less和Swap方法的切片类型。
|
||||
|
||||
```go
|
||||
type byArtist []*Track
|
||||
@@ -124,7 +124,7 @@ Go Delilah From the Roots Up 2012 3m38s
|
||||
Go Ahead Alicia Keys As I Am 2007 4m36s
|
||||
```
|
||||
|
||||
sort.Reverse函数值得进行更近一步的学习因为它使用了(§6.3)章中的组合,这是一个重要的思路。sort包定义了一个不公开的struct类型reverse,它嵌入了一个sort.Interface。reverse的Less方法调用了内嵌的sort.Interface值的Less方法,但是通过交换索引的方式使排序结果变成逆序。
|
||||
sort.Reverse函数值得进行更近一步的学习,因为它使用了(§6.3)章中的组合,这是一个重要的思路。sort包定义了一个不公开的struct类型reverse,它嵌入了一个sort.Interface。reverse的Less方法调用了内嵌的sort.Interface值的Less方法,但是通过交换索引的方式使排序结果变成逆序。
|
||||
|
||||
```go
|
||||
package sort
|
||||
@@ -136,7 +136,7 @@ func (r reverse) Less(i, j int) bool { return r.Interface.Less(j, i) }
|
||||
func Reverse(data Interface) Interface { return reverse{data} }
|
||||
```
|
||||
|
||||
reverse的另外两个方法Len和Swap隐式地由原有内嵌的sort.Interface提供。因为reverse是一个不公开的类型,所以导出函数Reverse函数返回一个包含原有sort.Interface值的reverse类型实例。
|
||||
reverse的另外两个方法Len和Swap隐式地由原有内嵌的sort.Interface提供。因为reverse是一个不公开的类型,所以导出函数Reverse返回一个包含原有sort.Interface值的reverse类型实例。
|
||||
|
||||
为了可以按照不同的列进行排序,我们必须定义一个新的类型例如byYear:
|
||||
|
||||
@@ -166,9 +166,9 @@ type customSort struct {
|
||||
less func(x, y *Track) bool
|
||||
}
|
||||
|
||||
func (x customSort) Len() int
|
||||
func (x customSort) Len() int { return len(x.t) }
|
||||
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] }
|
||||
func (x customSort) Swap(i, j int) { x.t[i], x.t[j] = x.t[j], x.t[i] }
|
||||
```
|
||||
|
||||
让我们定义一个多层的排序函数,它主要的排序键是标题,第二个键是年,第三个键是运行时间Length。下面是该排序的调用,其中这个排序使用了匿名排序函数:
|
||||
@@ -199,7 +199,7 @@ 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类型的使用:
|
||||
尽管对长度为n的序列排序需要 O(n log n)次比较操作,检查一个序列是否已经有序至少需要n-1次比较。sort包中的IsSorted函数帮我们做这样的检查。像sort.Sort一样,它也使用sort.Interface对这个序列和它的排序函数进行抽象,但是它从不会调用Swap方法:这段代码示范了IntsAreSorted和Ints函数在IntSlice类型上的使用:
|
||||
|
||||
```go
|
||||
values := []int{3, 1, 4, 1}
|
||||
|
||||
Reference in New Issue
Block a user