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 b
is true
if onlya
或 only b
is 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試試這個。
- 1 回答
- 0 關注
- 152 瀏覽
添加回答
舉報