Tertib `sort.Slice` tidak ditentukan

王林
Lepaskan: 2024-02-10 12:12:10
ke hadapan
1097 orang telah melayarinya

`sort.Slice` 顺序是不确定的

editor php Strawberry akan memperkenalkan anda beberapa maklumat penting tentang fungsi `sort.Slice`. Dalam bahasa Go, fungsi `sort.Slice` digunakan untuk mengisih hirisan, tetapi susunan hasil isihannya tidak ditentukan. Iaitu, untuk kepingan input yang sama, hasil pengisihan mungkin berbeza setiap kali. Ini kerana fungsi `sort.Slice` menggunakan algoritma pengisihan yang pantas dan cekap, tetapi susunan pengisihan khusus adalah berdasarkan keadaan khusus data input. Oleh itu, apabila menggunakan fungsi `sort.Slice`, kita harus sedar tentang ketidakpastian keputusan pengisihan untuk mengelakkan masalah dalam senario yang bergantung pada susunan pengisihan tertentu.

Kandungan soalan

Saya cuba menggunakan sort.slice 对字符串切片进行排序。我希望它们按字母顺序排序,除了我希望空字符串出现在所有其他字符串之后(因此我不能只使用 sort.strings) daripada perpustakaan standard go.

Untuk fungsi yang kurang, saya rasa ini akan berkesan:

func(i, j int) bool {
    return s[j] == "" || s[i] < s[j]
}
Salin selepas log masuk

Namun, saya nampaknya mendapat jawapan rawak berdasarkan susunan penyertaan. Ini adalah mwe:

package main

import (
    "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)
}
Salin selepas log masuk

Ini adalah hasil daripada menjalankannya beberapa kali:

$ 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"]
Salin selepas log masuk

Penyelesaian

Ini kerana fungsi less() anda tidak menyatakan apa yang anda mahukan.

Anda berkata anda mahu rentetan kosong diisih selepas semua rentetan bukan kosong. Logik anda:

return s[j] == "" || s[i] < s[j]
Salin selepas log masuk

Ini memberitahu kami jika yang kedua adalah "",那么第一个就更少。这或多或少是正确的(除非两者都是空的,“is-less”并不是真的:它们是相等的)。但是,如果第一个是 "" 而第二个不是怎么办?那么你的函数应该返回 false 但它返回 s[i] < s[j]。如果第二个不为空,则为 true,告诉 "" lebih kecil daripada yang lain, yang betul-betul bertentangan dengan apa yang anda mahukan.

Hubungan "is-less" yang betul adalah seperti ini:

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]
})
Salin selepas log masuk

Jika hanya yang kedua "", anda mahu yang pertama kurang. Jika hanya yang pertama kosong, anda mahu ia "tidak kurang daripada". Jika tidak, tertib biasa (byte-wise) digunakan.

Cubalah di pergi taman permainan.

Perhatikan bahawa jika kedua-dua nilai pertama dan kedua kosong, fungsi ini akan mengembalikan false kerana false,因为 "" 不小于 "" (它们相等)。这是要返回的正确值,尽管在此处返回 true tidak kurang daripada

(ia adalah sama). Ini adalah nilai yang betul untuk dikembalikan, walaupun mengembalikan true di sini masih akan menghasilkan susunan yang betul (menukar elemen kosong akan menghasilkan hasil yang sama), tetapi ini mungkin menghasilkan swap yang lebih sedikit.

Gunakan logik transformasi xor

Sila ambil perhatian bahawa dalam logik tersuai, jika hanya satu rentetan kosong, ia akan menyimpang daripada susunan biasa. Ini ialah hubungan logik XOR (XOR)a xor btrue 如果只有 a 或只有 btrue。在 go 中,没有逻辑 xor 运算符,但 a xor b 相当于 a != b:

.

true(否则为 falseJika rentetan kosong "dikesan", hasilnya ialah

jika rentetan kosong kedua kosong). Jadi kita boleh menggunakan transformasi identiti ini kepada logik kita:

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]
})
Salin selepas log masuk
Ini lebih pendek dan mungkin lebih cekap, tetapi seperti yang anda lihat, ia lebih sukar untuk difahami. Gunakan pilihan ini hanya jika prestasi adalah penting. Cuba ini di pergi taman permainan. 🎜

Atas ialah kandungan terperinci Tertib `sort.Slice` tidak ditentukan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!