Я хочу сравнить 2 строки rune-by-rune, чтобы увидеть, какой из них идет первым в произвольном алфавитном порядке.Iterate over 2 strings in go
Прямо сейчас у меня есть эта реализация, которая хранит в map[rune]int
сопоставление, представляющее порядок букв в моем алфавите.
У меня этот рабочий код. Я хорошо знаю недостатки в текущем проекте, но это не вопрос.
package main
import (
"bufio"
"log"
"math/rand"
"os"
"sort"
)
type Dictionnary struct {
content []string
alphaBeticalOrder map[rune]int
}
func minSize(w1, w2 []rune) int {
if len(w1) < len(w2) {
return len(w1)
}
return len(w2)
}
func (d *Dictionnary) comesFirst(a, b rune) int {
return d.alphaBeticalOrder[a] - d.alphaBeticalOrder[b]
}
func (d Dictionnary) Less(i, j int) bool {
wordi, wordj := []rune(d.content[i]), []rune(d.content[j])
size := minSize(wordi, wordj)
for index := 0; index < size; index++ {
diff := d.comesFirst(wordi[index], wordj[index])
switch {
case diff < 0:
return true
case diff > 0:
return false
default:
continue
}
}
return len(wordi) < len(wordj)
}
func (d Dictionnary) Swap(i, j int) {
d.content[i], d.content[j] = d.content[j], d.content[i]
}
func (d Dictionnary) Len() int {
return len(d.content)
}
func main() {
letters := []rune{'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm', 'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'}
aOrder := make(map[rune]int)
perm := rand.Perm(len(letters))
for i, v := range perm {
aOrder[letters[i]] = v
}
file, err := os.Open("testdata/corpus.txt")
if err != nil {
log.Fatal(err)
}
corpus := make([]string, 0, 1000)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
corpus = append(corpus, scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
file.Close()
input := Dictionnary{content: corpus, alphaBeticalOrder: aOrder}
sort.Sort(input)
ofile, err := os.Create("testdata/sorted.txt")
writer := bufio.NewWriter(ofile)
for _, v := range input.content {
writer.WriteString(v)
writer.WriteString("\n")
}
writer.Flush()
defer ofile.Close()
}
Мой вопрос касается функции Less(i,j int) bool
. Есть ли более идиоматический способ перебора более двух строк, чтобы сравнить их руну руны? Я делаю копию данных здесь, чего, вероятно, можно избежать.
EDIT: Чтобы уточнить, что проблема заключается в том, что диапазон (строка) может позволить вам выполнять итерацию по строкам rune by rune, но я не вижу способа перебора более двух строк бок о бок. Только так я вижу его, чтобы преобразовать строки в [] руну.
почему бы не использовать функции сравнения строк в 'sort' пакета? http://golang.org/pkg/sort/#Strings –
@Not_a_Golfer, потому что у него есть собственный алфавит. 'sort.Strings' будет использовать реализацию' sort.StringSlice', сортируя по «нормальному» алфавиту. – thwd
@tomwilde не выглядит таким обычаем для меня '[] rune {'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r ',' q ',' p ',' o ',' n ',' m ',' l ',' k ',' j ',' i ',' h ',' g ',' f ', 'e', 'd', 'c', 'b', 'a'} ' –