如何对字符串切片进行排序

huangapple go评论73阅读模式
英文:

How to sort a slice of string

问题

你的代码中使用了sort.SliceStable函数对字符串切片进行排序,但结果与输入相同,没有排序。这是因为你的比较函数返回的条件不正确。

在你的比较函数中,你使用了hour_i < hour_j && min_i < min_j && sec_i < sec_j作为排序的条件。这会导致只有当每个时间单位都严格小于对应的另一个时间单位时,才会认为前一个元素小于后一个元素。这样的条件会导致排序结果不正确。

要正确排序,你可以使用以下条件:

return hour_i < hour_j || (hour_i == hour_j && min_i < min_j) || (hour_i == hour_j && min_i == min_j && sec_i < sec_j)

这样,如果小时部分不同,直接比较小时部分的大小;如果小时部分相同,再比较分钟部分的大小;如果分钟部分也相同,再比较秒部分的大小。

修改后的代码如下:

func main() {
	rows := []string{
		"1:2:8",
		"1:2:5",
		"1:2:6",
	}

	sort.SliceStable(rows, func(i, j int) bool {
		var hour_i, min_i, sec_i int
		var hour_j, min_j, sec_j int

		fmt.Sscanf(rows[i], "%d:%d:%d", &hour_i, &min_i, &sec_i)
		fmt.Sscanf(rows[j], "%d:%d:%d", &hour_j, &min_j, &sec_j)

		return hour_i < hour_j || (hour_i == hour_j && min_i < min_j) || (hour_i == hour_j && min_i == min_j && sec_i < sec_j)
	})

	for _, x := range rows {
		fmt.Println(x)
	}
}

这样修改后,你应该能够得到正确排序的结果。

英文:

I'm trying to sort a slice of string, which look like "hour:minute:second".

func main() {
	rows := []string{
		&quot;1:2:8&quot;,
		&quot;1:2:5&quot;,
		&quot;1:2:6&quot;,
	}

	sort.SliceStable(rows, func(i, j int) bool {
		var hour_i, min_i, sec_i int
		var hour_j, min_j, sec_j int

		fmt.Sscanf(rows[i], &quot;%d:%d:%d&quot;, &amp;hour_i, &amp;min_i, &amp;sec_i)
		fmt.Sscanf(rows[j], &quot;%d:%d:%d&quot;, &amp;hour_j, &amp;min_j, &amp;sec_j)

		return hour_i &lt; hour_j &amp;&amp; min_i &lt; min_j &amp;&amp; sec_i &lt; sec_j
	})

	for _, x := range rows {
		fmt.Println(x)
	}
}

But the result is same to the input, not sorted. Why is that?

答案1

得分: 3

你需要分别比较每个项目。

sort.SliceStable(rows, func(i, j int) bool {
	var hour_i, min_i, sec_i int
	var hour_j, min_j, sec_j int

	fmt.Sscanf(rows[i], "%d:%d:%d", &hour_i, &min_i, &sec_i)
	fmt.Sscanf(rows[j], "%d:%d:%d", &hour_j, &min_j, &sec_j)

	if hour_i < hour_j {
		return true
	}

	if min_i < min_j {
		return true
	}

	return sec_i < sec_j
})
英文:

You need to compare each item separately

sort.SliceStable(rows, func(i, j int) bool {
	var hour_i, min_i, sec_i int
	var hour_j, min_j, sec_j int

	fmt.Sscanf(rows[i], &quot;%d:%d:%d&quot;, &amp;hour_i, &amp;min_i, &amp;sec_i)
	fmt.Sscanf(rows[j], &quot;%d:%d:%d&quot;, &amp;hour_j, &amp;min_j, &amp;sec_j)

	if hour_i &lt; hour_j {
		return true
	}

	if min_i &lt; min_j {
		return true
	}

	return sec_i &lt; sec_j
})

答案2

得分: -1

你可以使用sort包中的简单sort.Strings()方法对切片进行排序,修改你的代码并按照以下逻辑进行排序:

package main

import (
	"fmt"
	"sort"
)

func main() {

	rows := []string{
		"1:2:8",
		"1:2:5",
		"1:2:6",
		"2:0:7",
		"1:0:6",
		"2:0:5",
	}

	sort.Strings(rows)
	for _, val := range rows {
		fmt.Println(val)
	}

}

输出结果:

1:0:6
1:2:5
1:2:6
1:2:8
2:0:5
2:0:7
英文:

You can sort your slice using simple sort.Strings() method from sort package,modifying your code and sorting it with the same logic as follows:

package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

func main() {

	rows := []string{
		&quot;1:2:8&quot;,
		&quot;1:2:5&quot;,
		&quot;1:2:6&quot;,
		&quot;2:0:7&quot;,
		&quot;1:0:6&quot;,
		&quot;2:0:5&quot;,
	}

	sort.Strings(rows)
	for _, val := range rows {
		fmt.Println(val)
	}

}

Output :

1:0:6
1:2:5
1:2:6
1:2:8
2:0:5
2:0:7

huangapple
  • 本文由 发表于 2021年8月11日 22:10:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/68743671.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定