亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

`sort.Slice` 順序是不確定的

`sort.Slice` 順序是不確定的

Go
隔江千里 2023-03-21 10:21:20
我正在嘗試使用sort.SliceGo 標準庫對一段字符串進行排序。我希望它們按字母順序排序,除了我希望空字符串出現在所有其他字符串之后(因此我不能只使用sort.Strings)。對于 less 功能,我認為這會起作用:func(i, j int) bool {    return s[j] == "" || s[i] < s[j]}但是,我似乎根據輸入順序得到隨機答案。這是一個 MWE:package mainimport (    "fmt"    "math/rand"    "sort"    "time")func main() {    s := []string{"", "foo", "bar", "baz"}    rand.Seed(time.Now().Unix())    rand.Shuffle(len(s), func(i, j int) {        s[i], s[j] = s[j], s[i]    })    fmt.Printf("%q\n", s)    sort.Slice(s, func(i, j int) bool {        return s[j] == "" || s[i] < s[j]    })    fmt.Printf("%q\n", s)}這是運行幾次的輸出:$ go run ./z["" "foo" "baz" "bar"]["bar" "baz" "foo" ""]$ go run ./z["baz" "" "foo" "bar"]["bar" "" "baz" "foo"]$ go run ./z["bar" "foo" "" "baz"]["" "bar" "baz" "foo"]$ go run ./z["bar" "foo" "baz" ""]["" "bar" "baz" "foo"]
查看完整描述

1 回答

?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

這是因為您的less()功能并沒有說出您想說的話。


您說您希望在所有非空字符串之后對空字符串進行排序。你的邏輯:


return s[j] == "" || s[i] < s[j]

這確實告訴如果第二個是"",那么第一個就更少了。這或多或少是正確的(除非兩者都是空的,“is-less”不是真的:它們是相等的)。但是,如果第一個是""而第二個不是呢?然后你的函數應該返回false但它返回s[i] < s[j]。如果第二個不是空的,這將是true, telling ""is less than the other,與你想要的完全相反。


正確的“is-less”關系是這樣的:


sort.Slice(s, func(i, j int) bool {

    if s[j] == "" && s[i] != "" {

        return true

    }

    if s[i] == "" && s[j] != "" {

        return false

    }

    return s[i] < s[j]

})

如果只有第二個是"",您希望第一個更少。如果只有第一個是空的,你希望它“不會少”。否則使用正常順序(按字節順序)。

在Go Playground上嘗試一下。

請注意,如果第一個和第二個值均為空,則此函數將返回,false因為""不小于""(它們相等)。這是要返回的正確值,盡管返回true此處仍會導致正確的順序(交換空元素會導致相同的結果),但這可能會導致更少的交換。

使用 XOR 轉換邏輯

請注意,在自定義邏輯中,如果只有一個字符串為空,則與正常順序有偏差。這是邏輯 XOR(異或)關系a XOR bis trueif onlya或 only bis true。Go 中沒有邏輯XOR運算符,但a XOR b等同于a != b.

如果“檢測到”一個空字符串,則結果是true第二個是否為空(else false)。所以我們可以將這種身份轉換應用到我們的邏輯中:


sort.Slice(s, func(i, j int) bool {

    // Move empty elements to the end:

    if (s[i] == "") != (s[j] == "") { // If only one is empty

        return s[j] == ""

    }

    return s[i] < s[j]

})

這更短并且可能更有效,但如您所見,它更難理解。僅當性能很重要時才使用它。在Go Playground試試這個。



查看完整回答
反對 回復 2023-03-21
  • 1 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號