• Go程序设计语言练习题-第4章(4.1-4.9)


    4.1

    package main
    
    import (
        "crypto/sha256"
        "fmt"
    )
    
    func popCount(b [32]byte) (res int) {
        for _, v := range b {
            n := int(v)
            for n > 0 {
                n = n & (n - 1)
                res++
            }
        }
        return
    }
    
    func main() {
        b := sha256.Sum256([]byte("x"))
        fmt.Println(popCount(b))
    }
    View Code

    4.2

    package main
    
    import (
        "crypto/sha256"
        "crypto/sha512"
        "flag"
        "fmt"
        "os"
    )
    
    var t = flag.Int("t", 2, "-t 2|3|5")
    
    func main() {
        flag.Parse()
        c := make([]byte, 1024)
        n, err := os.Stdin.Read(c)
        if err != nil {
            fmt.Println(err)
            return
        }
        switch *t {
        case 3:
            fmt.Printf("%x
    ", sha512.Sum384(c[0:n]))
        case 5:
            fmt.Printf("%x
    ", sha512.Sum512(c[0:n]))
        default:
            fmt.Printf("%x
    ", sha256.Sum256(c[0:n]))
        }
    }
    View Code

    4.3~4.7

    package main
    
    import (
        "fmt"
        "unicode"
        "unicode/utf8"
        "unsafe"
    )
    
    // 4.3 重写reverse函数,使用数组指针作为参数而不是slice
    // ?数组长度是类型的一部分
    func reverse(arr *[5]int) {
        length := len(*arr)
        for i, j := 0, length-1; i < j; i, j = i+1, j-1 {
            (*arr)[i], (*arr)[j] = (*arr)[j], (*arr)[i]
        }
    }
    
    // 4.4 编写函数rotate,实现一次遍历就可以完成元素旋转
    func rotate(s []int, n int) (t []int) {
        if n <= 0 || n >= len(s) {
            return s
        }
        t = make([]int, len(s))
        for i, v := range s {
            t[(i+n)%len(s)] = v
        }
        return
    }
    
    // rotate另一种思路:原地旋转,遍历两次
    func reverseSlice(s []int) {
        for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
            s[i], s[j] = s[j], s[i]
        }
    }
    func rotate2(s []int, n int) {
        if n > len(s) {
            fmt.Errorf("parameter n:%d is out of range(%d)", n, len(s))
            return
        }
        reverseSlice(s[0 : len(s)-n])
        reverseSlice(s[len(s)-n:])
        reverseSlice(s)
    }
    
    // 4.5 编写一个就地处理函数,用于去除[]string slice中相邻重复字符串元素
    func distinct(s []string) []string {
        dist := s[0:1]
        for i := 1; i < len(s); i++ {
            for s[i] != dist[len(dist)-1] {
                dist = append(dist, s[i])
            }
        }
        return dist
    }
    
    // 4.6 编写一个就地处理函数,用于将一个UTF-8编码的字节slice中所有相邻的Unicode空白字符(查看unicode.IsSpace)缩减为一个ASCII空白字符。
    func ex4_6(b []byte) []byte {
        var i int
        for i, l := 0, 0; l < len(b); {
            r, size := utf8.DecodeRune(b[i:])
            l += size
            if unicode.IsSpace(r) {
                if i > 0 && b[i-1] == byte(32) {
                    copy(b[i:], b[i+size:])
                } else {
                    b[i] = byte(32)
                    copy(b[i+1:], b[i+size:])
                    i++
                }
            } else {
                i += size
            }
        }
        return b[0:i]
    }
    
    // 4.7 修改函数reverse,来反转一个UTF-8编码字符串中的字符元素,传入参数是该字符串对应的字节slice类型([]byte)。是否可以做到不重新分配内存就实现该功能。
    func mbreverse(b []byte) []byte {
        var res []byte
        for i := len(b); i > 0; {
            r, size := utf8.DecodeLastRune(b[:i])
            res = append(res, []byte(string(r))...)
            i -= size
        }
        return res
    }
    
    func main() {
        // 4.3
        arr := [...]int{1, 2, 3, 4, 5}
        reverse(&arr)
        fmt.Println(arr)
    
        // 4.4
        r := []int{1, 2, 3, 4, 5}
        fmt.Println(rotate(r, 0))
        fmt.Println(rotate(r, 1))
        fmt.Println(rotate(r, 2))
        fmt.Println(rotate(r, 5))
        fmt.Println(rotate(r, 6))
    
        // 4.5
        s := []string{" ", " ", "aaa", " ", "bbb", "bbb", "c", "d", "d"}
        dist := distinct(s)
        fmt.Printf("原slice的底层数组地址:%p
    ", unsafe.Pointer(uintptr(unsafe.Pointer(&s))))
        fmt.Printf("原slice的len:%d
    ", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + unsafe.Sizeof(&s))))
        fmt.Printf("原slice的cap:%d
    ", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + 2*unsafe.Sizeof(&s))))
    
        fmt.Printf("去重后底层数组地址:%p
    ", unsafe.Pointer(uintptr(unsafe.Pointer(&dist))))
        fmt.Printf("len:%d
    ", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&dist)) + unsafe.Sizeof(&dist))))
        fmt.Printf("cap:%d
    ", *(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&dist)) + 2*unsafe.Sizeof(&dist))))
    
        // 4.6
        b := []byte("北京	欢迎
    您")
        fmt.Printf("%s
    %v
    ", b, b)
        ex4_6(b)
        fmt.Printf("%s
    %v
    ", b, b)
    
        // 4.7
        b = []byte("北京欢迎您welcome")
        fmt.Printf("%s
    ", b)
        fmt.Printf("%s
    ", mbreverse(b))
    
    }
    View Code

     4.8~4.9

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "os"
        "unicode"
    )
    
    func charcount() {
        seen := make(map[rune]bool)
        var letterCount, numberCount, otherCount, invalid int
        in := bufio.NewReader(os.Stdin)
        for {
            r, n, err := in.ReadRune()
            if err == io.EOF {
                break
            }
            if err != nil {
                fmt.Fprintln(os.Stderr, "charcount:%v
    ", err)
                os.Exit(1)
            }
            if r == unicode.ReplacementChar && n == 1 {
                invalid++
                continue
            }
            if unicode.IsLetter(r) && !seen[r] {
                letterCount++
                seen[r] = true
                continue
            }
            if unicode.IsNumber(r) && !seen[r] {
                numberCount++
                seen[r] = true
                continue
            }
            if !seen[r] {
                otherCount++
                seen[r] = true
            }
        }
    
        fmt.Fprintf(os.Stdout, "letterCount:%d	numberCount:%d	otherCount:%d	invalidCount:%d
    ", letterCount, numberCount, otherCount, invalid)
    }
    
    // 4.9
    func wordfreq() map[string]int {
        scanner := bufio.NewScanner(os.Stdin)
        scanner.Split(bufio.ScanWords)
        words := make(map[string]int)
        for scanner.Scan() {
            words[scanner.Text()]++
        }
        if err := scanner.Err(); err != nil {
            fmt.Fprintln(os.Stderr, err)
        }
        return words
    }
    
    func main() {
        fmt.Println("ex4.8
    ")
        charcount()
    
        fmt.Println("ex4.9 Word Frequency:")
        words := wordfreq()
        for w, n := range words {
            fmt.Printf("%s	%d
    ", w, n)
        }
    }
    View Code
  • 相关阅读:
    [Bzoj2243][SDOI2011]染色(线段树&&树剖||LCT)
    [poj3074]Sudoku(舞蹈链)
    [Bzoj1047][HAOI2007]理想的正方形(ST表)
    [Bzoj1030][JSOI2007]文本生成器(AC自动机&dp)
    [Bzoj2431][HAOI2009]逆序对数列(前缀和优化dp)
    [Bzoj1072][SCOI2007]排列perm(状压dp)
    [Bzoj1195][HNOI2006]最短母串(AC自动机)
    Ajax解决IE浏览器兼容问题
    运行eclipse弹出“Failed to load the JNI shared”解决方法
    Java表单类双击提交
  • 原文地址:https://www.cnblogs.com/ling-diary/p/10408376.html
Copyright © 2020-2023  润新知