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\n%s\n%s\n", "Hello World", "Second Line", "Third Line")
    fmt.Println(lc) // 3
    fmt.Fprintf(&lc, "%s\n%s\n%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

 

转载于:https://www.cnblogs.com/ling-diary/p/10294916.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值