《go语言程序设计》学习(六)

一,缩紧排序

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

《go语言程序设计》学习(六)的相关文章

C语言程序设计学习心得

一,思维导图 二,语法认识 1,if-else的用法 if (条件一) { 语句一; } else { 语句二; } 问题:else与if的匹配关系不明确,导致程序异常. 解决方法:牢记else与离其最近的一个if配对,不与其他的if连用,并规范代码书写格式,使其看起来跟加清晰明了. 2,while语句的用法 while (循环条件) { 循环语句; } 注意事项:while比较好用,基本上所有的循环结构都能用while写. 3,for语句的用法 for(表达式1; 表达式2; 表达式3) {

C语言程序设计第六次作业

(一)改错题 序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数). 输入输出样例: Input eps:1E-4 s = 0.835699 源程序(有错误的程序) #include<stdio.h> int main() { int flag,n; double eps,item,s; printf("Input eps: "); scanf("%f",

c语言程序设计第六次作业——循环结构(2)

(一)改错题 序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数). 修改前的源代码 错误信息(1): 错误原因:用do while循环语句在while后面要加分号,这个语句特殊需牢记 改正方法:在while后面加上分号 错误信息(2): 错误原因:item = 1/ n;次语句中n定义为整型,所以1/n不会出现小数 改正方法:把 item = 1/ n; 改为 item = (double)1/

C语言程序设计第六次作业--循环结构2

(一)改错题 序列求和:输入一个正实数eps,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... ,精确到最后一项的绝对值小于eps(保留6位小数). 输入输出样例: Input eps:1E-4 s = 0.835699 源程序(有错误的程序) #include<stdio.h> int main() { int flag,n; double eps,item,s; printf("Input eps: "); scanf("%f",

JavaScript高级程序设计学习(六)之设计模式

每种编程语言都有其自己的设计模式.不禁让人疑惑设计模式是用来做什么?有什么用? 简单的说,设计模式是为了让代码更简洁,更优雅,更完美. 同时设计模式也会让软件的性能更好,同时也会让程序员们更轻松.设计模式可谓是编程界的"葵花宝典"或"辟邪剑法".如果一旦练成,必可在编程界中来去自如,游刃有余. 下面进入正题 (1)工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程(本书后 面还将讨论其他设计模式及其在 JavaScript中的实

中国大学MOOC-翁恺-C语言程序设计习题集

Technorati 标签: 中国大学MOOC-翁恺-C语言程序设计习题集,C 今年网易出了"中国大学MOOC",于是选了浙大翁恺老师的"C语言程序设计"学习,近期打算把自己在该课程中的PAT习题解答做一个记录,等自己编程能力提高后再来看现在写的代码哪里还有写的不好,可以改进的地方,达到反思的目的.   中国大学MOOC-翁恺-C语言程序设计习题集,布布扣,bubuko.com

学习《C语言程序设计第四版.谭浩强》计划

1.每天学习一个章节 2.所有的课程代码手动创建.生成 3.完成课后习题 4.每章节发表博客 5.每章节写笔记 第一章:程序设计和C语言 第二章:算法--程序的灵魂 第三章:最简单的C程序设计--顺序程序设计 第四章:选择结构程序设计 第五章:循环结构程序设计 第六章:利用数组处理批量数据 第七章:用函数实现模块化程序设计 第八章:善于利用指针 第九章:用户自己建立数据类型 第十章:对文件的输入输出 第十一章:常见错误分析

程序设计入门学习六步曲

初学者遇到最多的困惑是:上课也能听懂,书上的例题也能看明白,可是到自己动手做编程时,却不知道如何下手.发生这种现象的原因有三个: 一.所谓的看懂听明白,只是很肤浅的语法知识,而我们编写的程序或软件是要根据要解决问题的实际需要控制程序的流程,如果你没有深刻地理解C语言的语句的执行过程(或流程),你怎么会编写程序解决这些实际问题呢? 二.用C语言编程解决实际问题,所需要的不仅仅是C语言的编程知识,还需要相关的专业知识.例如,如果你不知道长方形的面积公式,即使C语言学得再好你也编不出求长方形的面积的程

2018年秋季学期《c语言程序设计》学习总结

<c语言程序设计>第四周学习总结 <c语言程序设计>第五周学习总结 <c语言程序设计>第六周学习总结 <c语言程序设计>第七周学习总结 <c语言程序设计>第八周学习总结 <c语言程序设计>第九周学习总结 <c语言程序设计>第十周学习总结 <c语言程序设计>第十一周学习总结 <c语言程序设计>第十二周学习总结 <c语言程序设计>第十三周学习总结 原文地址:https://www.cnblo

初探swift语言的学习笔记六(ARC-自动引用计数,内存管理)

Swift使用自动引用计数(ARC)来管理应用程序的内存使用.这表示内存管理已经是Swift的一部分,在大多数情况下,你并不需要考虑内存的管理.当实例并不再被需要时,ARC会自动释放这些实例所使用的内存. 另外需要注意的: 引用计数仅仅作用于类实例上.结构和枚举是值类型,而非引用类型,所以不能被引用存储和传递. swift的ARC工作过程 每当创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息. 另外当实例不再被使用时,ARC会释放实例所占用的内存,这些