4.1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)) }
4.2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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])) } }
4.3~4.7
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)) }
4.8~4.9
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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) } }