zoukankan      html  css  js  c++  java
  • Go程序设计语言练习题(7.1-7.10)

    7.1:使用类似ByteCounter的想法,实现单词和行的计数器,实现时考虑使用bufio.ScanWords。

    package main
    
    import (
        "bufio"
        "fmt"
    )
    
    type WordsCounter int
    
    func (c *WordsCounter) Write(content []byte) (int, error) {
        for start := 0; start < len(content); {
            //跳过开头的space,返回遇到第一个word后下次scan的开始index
            //Hello Worlds 调用bufio.ScanWords返回
            //6 [Hello的字节slice] nil
            advance, _, err := bufio.ScanWords(content[start:], true)
            if err != nil {
                return 0, err
            }
            start += advance
            (*c)++
        }
        return int(*c), nil
    }
    
    type LinesCounter int
    
    func (c *LinesCounter) Write(content []byte) (int, error) {
        for start := 0; start < len(content); {
            advance, _, err := bufio.ScanLines(content[start:], true)
            if err != nil {
                return 0, err
            }
            start += advance
            (*c)++
        }
        return int(*c), nil
    }
    
    func main() {
        var wc WordsCounter
        wc.Write([]byte("Hello Worlds Test Me"))
        fmt.Println(wc) // 4
        wc.Write([]byte("append something to the end"))
        fmt.Println(wc) // 9
    
        var lc LinesCounter
        fmt.Fprintf(&lc, "%s
    %s
    %s
    ", "Hello World", "Second Line", "Third Line")
        fmt.Println(lc) // 3
        fmt.Fprintf(&lc, "%s
    %s
    %s", "第4行", "第5行", "")
        fmt.Println(lc) // 5
    }
    View Code

    7.2:实现一个满足如下签名的CountingWriter函数,输入一个io.Writer,输出一个封装了输入值的心Writer,以及一个置项int64的指针,改制真对应的值是新的Writer吸入的字节数。

    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    
    type CountWriter struct {
        Writer io.Writer
        Count  int
    }
    
    func (cw *CountWriter) Write(content []byte) (int, error) {
        n, err := cw.Writer.Write(content)
        if err != nil {
            return n, err
        }
        cw.Count += n
        return n, nil
    }
    
    func CountingWriter(writer io.Writer) (io.Writer, *int) {
        cw := CountWriter{
            Writer: writer,
        }
        return &cw, &(cw.Count)
    }
    
    func main() {
        cw, counter := CountingWriter(os.Stdout)
        fmt.Fprintf(cw, "%s", "Print somethind to the screen...")
        fmt.Println(*counter)
        cw.Write([]byte("Append soething..."))
        fmt.Println(*counter)
    }
    View Code

    7.3:为gopl.io/ch4/treesort中的*tree类型写一个String方法,用于展示其中的值序列。

    package main
    
    import (
        "fmt"
        "math/rand"
    )
    
    type tree struct {
        value       int
        left, right *tree
    }
    
    func (t *tree) String() string {
        res := ""
        if t == nil {
            return res
        }
        res += t.left.String()
        res = fmt.Sprintf("%s %d", res, t.value)
        res += t.right.String()
        return res
    }
    func buildTree(data []int) *tree {
        var root = new(tree)
        for _, v := range data {
            root = add(root, v)
        }
        return root
    }
    func add(t *tree, e int) *tree {
        if t == nil {
            t = new(tree)
            t.value = e
            return t
        }
    
        if e < t.value {
            t.left = add(t.left, e)
        } else {
            t.right = add(t.right, e)
        }
        return t
    }
    
    func main() {
        data := make([]int, 50)
        for i := range data {
            data[i] = rand.Int() % 50
        }
        root := buildTree(data)
        fmt.Println(root)
    
        //空指针
        fmt.Println(new(tree))
    
        //只有根节点
        root = new(tree)
        root.value = 100
        fmt.Println(root)
    
        //没有右子树
        data = []int{5, 4, 3, 2, 1}
        root = buildTree(data)
        fmt.Println(root)
    
        //没有左子树
        data = []int{1, 3, 2, 4, 5}
        root = buildTree(data)
        fmt.Println(root)
    }
    View Code

    7.4:strings.NewReader函数输入一个字符串,返回一个从字符串读取数据并满足io.Reader接口的值。请实现该函数。

    package main
    
    import (
        "fmt"
        "io"
    )
    
    type StringReader struct {
        data string
        n    int
    }
    
    func (sr *StringReader) Read(b []byte) (int, error) {
        data := []byte(sr.data)
        if sr.n >= len(data) {
            return 0, io.EOF
        }
    
        data = data[sr.n:]
        n := 0
        if len(b) >= len(data) {
            n = copy(b, data)
            sr.n = sr.n + n
            return n, nil
        }
        n = copy(b, data)
        sr.n = sr.n + n
        return n, nil
    }
    
    func NewReader(in string) *StringReader {
        sr := new(StringReader)
        sr.data = in
        return sr
    }
    
    func main() {
        str := "Hello World"
        sr := NewReader(str)
        data := make([]byte, 10)
        n, err := sr.Read(data)
        for err == nil {
            fmt.Println(n, string(data[0:n]))
            n, err = sr.Read(data)
        }
    }
    View Code

    7.5:io包中的LimitReader函数接受一个io.Reader r和字节数n,返回一个Reader,该返回值从r读取数据,但在读取n字节后报告文件结束,请实现该函数。

    func LimitReader(r io.Reader,n int64) io.Reader

    package main
    
    import (
        "fmt"
        "io"
        "os"
    )
    
    type LimitedReader struct {
        Reader  io.Reader
        Limit   int
        current int
    }
    
    func (r *LimitedReader) Read(b []byte) (int, error) {
        if r.current >= r.Limit {
            return 0, io.EOF
        }
    
        if r.current+len(b) > r.Limit {
            b = b[:r.Limit-r.current]
        }
        n, err := r.Reader.Read(b)
        if err != nil {
            return n, err
        }
        r.current += n
        return n, nil
    }
    
    func LimitReader(r io.Reader, limit int) io.Reader {
        lr := LimitedReader{
            Reader: r,
            Limit:  limit,
        }
        return &lr
    }
    
    func main() {
        file, err := os.Open("limit.txt") // 1234567890
        if err != nil {
            panic(err)
        }
        defer file.Close()
    
        lr := LimitReader(file, 5)
        buf := make([]byte, 10)
        n, err := lr.Read(buf)
        if err != nil {
            panic(err)
        }
        fmt.Println(n, buf) // 5 [49 50 51 52 53 0 0 0 0 0]
    }
    View Code

    7.8:(先实现一部分)将多个排序方法存到一个slice中,先按最后的方法排序,再按之前的方法排序。

    package main
    
    import (
        "fmt"
        "sort"
    )
    
    type book struct {
        name   string
        price  float64
        author string
    }
    type byFunc func(i, j int) bool
    type tableSlice struct {
        lists     []*book
        lessFuncs []byFunc
    }
    
    func (ts tableSlice) Len() int {
        return len(ts.lists)
    }
    func (ts tableSlice) Swap(i, j int) {
        ts.lists[i], ts.lists[j] = ts.lists[j], ts.lists[i]
    }
    func (ts tableSlice) Less(i, j int) bool {
        for t := len(ts.lessFuncs) - 1; t >= 0; t-- {
            if ts.lessFuncs[t](i, j) {
                return true
            } else if !ts.lessFuncs[t](j, i) {
                continue
            } else {
                return false
            }
        }
        return false
    }
    
    func (ts tableSlice) byName(i, j int) bool {
        return ts.lists[i].name < ts.lists[j].name
    }
    func (ts tableSlice) byPrice(i, j int) bool {
        return ts.lists[i].price < ts.lists[j].price
    }
    
    func main() {
        book1 := book{"GoLang", 65.50, "Aideng"}
        book2 := book{"PHP", 45.50, "Sombody"}
        book3 := book{"C", 45.50, "Tan"}
        ts := tableSlice{
            lists: []*book{&book1, &book2, &book3},
        }
        ts.lessFuncs = []byFunc{ts.byName, ts.byPrice}
        sort.Sort(ts)
        for _, book := range ts.lists {
            fmt.Println(*book)
        }
    }
    View Code

    7.10:写一个函数IsPalindrome(s sort.Interface)bool判断一个序列是否是回文。

    package palindrome
    
    import (
        "fmt"
        "sort"
    )
    
    func IsPalindrome(s sort.Interface) bool {
        if s.Len() == 0 {
            return false
        }
        i, j := 0, s.Len()-1
        for i < j {
            if !s.Less(i, j) && !s.Less(j, i) {
                i++
                j--
            } else {
                return false
            }
        }
        return true
    }
    
    func main() {
        a := []int{1, 2, 3, 2, 1}
        fmt.Println(IsPalindrome(sort.IntSlice(a))) // true
        a = []int{2, 1, 3, 4, 5}
        fmt.Println(IsPalindrome(sort.IntSlice(a))) //false
        a = []int{1}
        fmt.Println(IsPalindrome(sort.IntSlice(a))) // true
        a = []int{}
        fmt.Println(IsPalindrome(sort.IntSlice(a))) // false
    }
    View Code
  • 相关阅读:
    C#
    C#
    ssh学习笔记
    (已解决)Could not open '/var/lib/nova/mnt/*/volume-*': Permission denied
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    如何在linux下安装idea
    The system has no LUN copy license
    调整mysql数据库最大连接数
    mysql数据库编码问题
    cinder支持nfs快照
  • 原文地址:https://www.cnblogs.com/ling-diary/p/10294916.html
Copyright © 2011-2022 走看看