一,缩紧排序
package main import ( "fmt" "sort" "strings" ) var original = []string{ "Nonmentals", " Hydrogen", " Carbon", " Nitrogenl", " Oxygen", "Inner Transitionals", " Lanthanides", " Europium", " Cerium", " Actinides", " Uranium", " Plutonium", " Curium", "Alkali Metals", " Lithium", " Sodium", " Potassium", } func main() { fmt.Println("| Original | Sorted |") fmt.Println("|----------------------|-------------------|") sorted := SortedIndentedStrings(original) for i := range original { fmt.Printf("|%-19s|%-19s|\n", original[i], sorted[i]) } } func SortedIndentedStrings(slice []string) []string { entries := populatedEntries(slice) return sortedEntries(entries) } func populatedEntries(slice []string) Entries { indent, IndentSize := computeIndent(slice) fmt.Printf("[%s] %d = %d\n", indent, len(indent), IndentSize) entries := make(Entries, 0) for _, item := range slice { i, level := 0, 0 for strings.HasPrefix(item[i:], indent) { i += IndentSize level++ } key := strings.ToLower(strings.TrimSpace(item)) addEntry(level, key, item, &entries) } return entries } func computeIndent(slice []string) (string, int) { for _, item := range slice { if len(item) > 0 && (item[0] == ‘ ‘ || item[0] == ‘\t‘) { whitspace := rune(item[0]) for i, char := range item[1:] { if char != whitspace { i++ return strings.Repeat(string(whitspace), i), i } } } } return "", 0 } func addEntry(level int, key, value string, entries *Entries) { if level == 0 { *entries = append(*entries, Entry{key, value, make(Entries, 0)}) } else { addEntry(level-1, key, value, &((*entries)[entries.Len()-1].children)) } } func sortedEntries(entries Entries) []string { var indentedSlice []string sort.Sort(entries) for _, entry := range entries { populatedIndentedStrings(entry, &indentedSlice) } return indentedSlice } func populatedIndentedStrings(entry Entry, indentedSlice *[]string) { *indentedSlice = append(*indentedSlice, entry.value) sort.Sort(entry.children) for _, child := range entry.children { populatedIndentedStrings(child, indentedSlice) } } type Entry struct { key string value string children Entries } type Entries []Entry func (entries Entries) Len() int { return len(entries) } func (entries Entries) Less(i, j int) bool { return entries[i].key < entries[j].key } func (entries Entries) Swap(i, j int) { entries[i], entries[j] = entries[j], entries[i] }
这个代码,还是很简单,不过还不算很完美,因为有一个假定的前提——所有文本行都使用相同的缩紧。
代码逻辑:
首先遍历所有行数据,直到找到一行,是用空格活着tab开头的文字,并获取这行有多少个该字符,以此作为判定缩紧等级的基础。
然后再次便利所有行数据,用string.hasPrefix获取反复对字符串“开头”进行计算,计算结果即缩紧等级。
使用缩紧等级构造数据结构Entry,缩紧为0,则新增根Entrie,缩紧为1,则在根Entry的child上,构建改Entry,为2,则在Entry的child的child上构建。
最后使用定义的Less方法做字符串的比较,对每个根的每一层Entry分别进行sort。
使用的数据结构,如果假设有一个叫root的Entry节点,就可以认为是一棵树啦。
时间: 2024-10-12 00:48:21