当前位置: 代码迷 >> 综合 >> GOPL Exercise
  详细解决方案

GOPL Exercise

热度:60   发布时间:2023-11-26 02:12:36.0

EX 3.10

练习 3.10: 编写一个非递归版本的comma函数,使用bytes.Buffer代替字符串链接操作。

func comma(s string) string {
    var buf bytes.Buffern := len(s)fmt.Println(n)if n <= 3 {
    return s}for i := n; i > 0; i-- {
    if i%3 == 0 && i != n {
    buf.WriteByte(',')}buf.WriteByte(s[n-i])}return buf.String()
}

EX 3.11

练习 3.11: 完善comma函数,以支持浮点数处理和一个可选的正负号的处理。

func comma(s string) string {
    var buf bytes.BuffermantissaStart := 0if s[0] == '+' || s[0] == '-' {
    buf.WriteByte(s[0])mantissaStart = 1}mantissaEnd := strings.Index(s, ".")if mantissaEnd == -1 {
    mantissaEnd = len(s)}mantissa := s[mantissaStart:mantissaEnd]n := len(mantissa)if n <= 3 {
    buf.WriteString(mantissa)} else {
    for i := n; i > 0; i-- {
    if i%3 == 0 && i != n {
    buf.WriteByte(',')}buf.WriteByte(mantissa[n-i])}}buf.WriteString(s[mantissaEnd:])return buf.String()
}

EX 3.12

练习 3.12: 编写一个函数,判断两个字符串是否是相互打乱的,也就是说它们有着相同的字符,但是对应不同的顺序。

// 一
func isAnagram1(a, b string) bool {
    j := 0for i := 0; i < len(a); i++ {
    if strings.Count(a, a[i:i+1]) == strings.Count(b, a[i:i+1]) {
    j++}}if !strings.EqualFold(a, b) && j == len(a) && len(a) == len(b) {
    return true}return false
}// 二
func isAnagram2(a, b string) bool {
    aFrep := make(map[rune]int)for _, c := range a {
    aFrep[c]++}bFrep := make(map[rune]int)for _, c := range b {
    bFrep[c]++}for k, v := range aFrep {
    if bFrep[k] != v {
    return false}}for k, v := range bFrep {
    if aFrep[k] != v {
    return false}}return true
}// 三
func isAnagram3(a, b string) bool {
    aFrep := make(map[rune]int)for _, c := range a {
    aFrep[c]++}bFrep := make(map[rune]int)for _, c := range b {
    bFrep[c]++}if reflect.DeepEqual(aFrep, bFrep) {
    return true}return false
}

EX 3.13

练习 3.13: 编写KB、MB的常量声明,然后扩展到YB。

const (KB = 1000MB = 1000 * KBGB = 1000 * MBPB = 1000 * GB
)

EX 7.1

练习 7.1: 使用来自ByteCounter的思路,实现一个针对单词和行数的计数器。你会发现bufio.ScanWords非常的有用。

type WordCounter intfunc (c *WordCounter) Write(p []byte) (int, error) {
    scanner := bufio.NewScanner(bytes.NewReader(p))scanner.Split(bufio.ScanWords)for scanner.Scan() {
    *c += WordCounter(1)}return 0, nil
}type LineCounter intfunc (c *LineCounter) Write(p []byte) (int, error) {
    scanner := bufio.NewScanner(bytes.NewReader(p))scanner.Split(bufio.ScanLines)for scanner.Scan() {
    *c += LineCounter(1)}return 0, nil
}

EX 7.2

练习 7.2: 写一个带有如下函数签名的函数CountingWriter,传入一个io.Writer接口类型,返回一个把原来的Writer封装在里面的新的Writer类型和一个表示新的写入字节数的int64类型指针。

type ByteCounter struct {
    w       io.Writerwritten int64
}func (c *ByteCounter) Write(p []byte) (int, error) {
    n, err := c.w.Write(p)c.written += int64(n)return n, err
}func CountingWriter(w io.Writer) (io.Writer, *int64) {
    c := ByteCounter{
    w, 0}return &c, &c.written
}

EX 7.3

练习 7.3: 为在gopl.io/ch4/treesort (§4.4)中的*tree类型实现一个String方法去展示tree类型的值序列。

func (t *tree) String() string {
    var s stringif t == nil {
    return s}s += t.left.String()if t.left != nil {
    s += ", "}s += strconv.Itoa(t.value)if t.right != nil {
    s += ", "}s += t.right.String()return s
}

EX 7.7

练习 7.7: 解释为什么帮助信息在它的默认值是20.0没有包含°C的情况下输出了°C。

因为 CelsiusFlag 拥有 Celsius 作为成员,而 Celsius 实现了 String 方法(实现了 fmt.Stringer 接口),
所以打印是会通过 Celsius.String() 输出