Go语言 基于子字符串的字母表对字符串片段进行排序

eqoofvh9  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(93)

我有一个单词列表,以及一个“字母”列表,这是我想要排序单词列表的顺序:

words    := []string{"kape","piki","na","nga","bube","babo","ninggi","baboninggi"}
alphabet := []string{"a","i","u","e","o","p","t","k","m","ng","n","b","d","g"}

expectedOrder := []string{"piki","kape","nga","na","ninggi","babo","baboninggi","bube"}

我试过使用herehere的方法,给alphabet中的每个字母一个map中的排名,但是这个答案只在匹配整个字符串时有效。在这里,我需要按“字母”排序,这些字母不一定是1个rune长(见上面的“ng”)。
一个符文一个符文的方法在这里也不起作用,因为,如上所述,字母不是符文,不一定是1个符文长。因此,“letter”可能包含其他字母作为子字符串,但在顺序中排在第一位(参见:上面的“nga”和“na”。一个符文接一个符文的方法会说顺序是na,nga,当字母说明顺序是nga,na)。
我怎么才能做到这一点,而不诉诸于O(n^2)或更糟的东西?

nr9pn0ug

nr9pn0ug1#

在链接的答案中使用相同概念的一种方法是通过将它们转换为新的字符串来创建特定于您的单词的排名,这些字符串将按照您想要的顺序进行比较。为了方便起见,我们将使用可打印的字符作为在字符串词法比较中使用的秩值。

// rank each letter of the alphabet, using ascii characters as the value

var alphabet = strings.NewReplacer(
    "a", "a",
    "i", "b",
    "u", "c",
    "e", "d",
    "o", "e",
    "p", "f",
    "t", "g",
    "k", "h",
    "m", "i",
    "ng", "j",
    "n", "k",
    "b", "l",
    "d", "m",
    "g", "n",
)

您可以按需翻译每个比较的单词

sort.Slice(words, func(i, j int) bool {
    return alphabet.Replace(words[i]) < alphabet.Replace(words[j])
})

或者,如果你想用内存来换取比较时间,你可以将所有的单词预翻译成一个新的字符串,并根据这些进行排序:

translated := make([]string, 0, len(words))
for _, word := range words {
    translated = append(translated, alphabet.Replace(word))
}
sort.Slice(translated, func(i, j int) bool {
    less := translated[i] < translated[j]
    // swap the actual words slice in conjunction with the translated slice
    if less {
        words[i], words[j] = words[j], words[i]
    }
    return less
})

https://go.dev/play/p/h2rBvsS_UI-

相关问题