Golang-C1-4

作业

read.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	f, err := os.Open("a.txt")
	if err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 1024)
	n, _ := f.Read(buf)
	fmt.Printf("%d\n###%s###\n", n, string(buf))
	f.Close()
}

ps.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"
)

func main() {
	f, err := os.Open("/proc") // 打开目录
	if err != nil {
		log.Fatal(err)

	}
	infos, _ := f.Readdir(-1)    // 读取目录下的文件或目录(结果类型是数组)
	for _, info := range infos { // 遍历结果,对目录为数字的(确定它是PID),读取目录下cmdline文件内容(该PID对应的命令)
		if !info.IsDir() {
			continue
		}
		infoname, err := strconv.Atoi(info.Name()) // 字符串转换为数字,如果不出err 说明其为数字
		if err != nil {                            // 没有异常
			continue
			// 打印PID,PID的命令名
		}
		filebuf, _ := ioutil.ReadFile(procdir + strconv.Itoa(infoname) + proccommand) // 读取cmdline文件内容
		fmt.Println(infoname, string(filebuf))

	}
	f.Close()
}

如何重构“箭头型”代码

img

复合数据类型

  • 数组,切片
  • map
  • 结构体
  • 序列化和反序列化

myexpr.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

package main

import (
	"fmt"
	"os"
	"strconv"
)

func main() {
	if len(os.Args) != 4 {
		fmt.Println("Usage: myexpr 1 + 2")
		return
	}

	x, err := strconv.Atoi(os.Args[1])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	y, err := strconv.Atoi(os.Args[3])
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	switch os.Args[2] {
	case "+":
		fmt.Printf("%v + %v = %v\n", x, y, x+y)
	case "-":
		fmt.Printf("%v - %v = %v\n", x, y, x-y)
	case "*":
                fmt.Printf("%v * %v = %v\n", x, y, x*y)
	case "/":
                fmt.Printf("%v / %v = %v\n", x, y, x/y)
	}

}

myps.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"sort"
	"strconv"
)

func main() {
	var pids []int
	dirs, err := ioutil.ReadDir("/proc")
	if err != nil {
		log.Fatal(err)
	}
	for _, dir := range dirs {
		n, err := strconv.Atoi(dir.Name())
		if err != nil {
			continue
		}
		pids = append(pids, n)
	}
	sort.Ints(pids)
	fmt.Println("PID\tCMD")
	//fmt.Println(pids)
	for _, pid := range pids {
		filename := fmt.Sprintf("%v/%v/%v", "/proc", pid, "cmdline")
		data, err := ioutil.ReadFile(filename)
		if err != nil {
			continue
		}
		fmt.Printf("%v\t%v\n", pid, string(data))
	}
}

reverser.go(只能反转英文)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

package main

import (
	"fmt"
)

func toReverser(s string) string {
	buf := []byte(s)
	for i, j :=0, len(buf)-1; i < j; i, j = i+1, j-1 {
		buf[i],buf[j] = buf[j],buf[i]
	}
	return string(buf)
}

func main() {
	s := "test, abc"
	fmt.Println(s)
	fmt.Println(toReverser(s))
}

reverser.go(可反转中文)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

package main

import (
	"fmt"
)

func Reverse(s string) string {
        /* can not chinese
           strs := []byte(s)
           for i, j := 0, len(strs)-1; i < j; i, j = i+1, j-1 {
                strs[i], strs[j] = strs[j], strs[i]
           }
           return string(strs)
        */
        runes := []rune(s)
        for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
                runes[i], runes[j] = runes[j], runes[i]
        }
        return string(runes)
}

func main() {
	var input string = "你好世界,just demo"
        // var input string = "just demo"
        fmt.Println("origin :", input)
        re_input := Reverse(input)
        fmt.Println("reverse :", re_input)
}

数组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package main

import "fmt"

func main() {
	var a [3]int
	fmt.Println(a[0])
	fmt.Println(a[len(a)-1])
	for i, v := range a {
		fmt.Printf("%d %d\n", i, v)
	}
	for _, v := range a {
		fmt.Printf("%d\n", v)
	}
}

array.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import (
	"fmt"
	"unsafe"
)

func main() {
	a1 := [3]int{1, 2, 3}
	var a2 [3]int
	a2 = a1
	fmt.Println(&a1[0], &a2[0])
	fmt.Println(unsafe.Sizeof(a1))
	var n1, n2 *int
	n1 = &a1[0]
	n2 = n1
	fmt.Println(n1, n2)
	fmt.Printf("%x\n", 255)
}

md5.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
	"crypto/md5"
	"fmt"
)

func main() {
	md5sum := md5.Sum([]byte("hello"))
	fmt.Printf("%s\n", md5sum)

	var b []byte
	b = []byte("hello")
	fmt.Printf("%v\n", b)

	md5sum1 := md5.Sum([]byte("hello1"))
	if md5sum == md5sum1 {
	}
	fmt.Println(md5sum)
}

数组的应用:md5

https://godoc.org/crypto/md5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

import (
	"crypto/md5"
	"fmt"
)

func main() {
	data := []byte("hello")
	md5sum := md5.Sum(data)
	fmt.Printf("%x\n", md5sum)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import (
	"crypto/md5"
	"fmt"
)

func main() {
	md5sum := md5.Sum([]byte("hello"))
	fmt.Printf("%x\n", md5sum)
	
	md5sum1 := md5.Sum([]byte("hello1"))
	if md5sum == md5sum1 {
	}
	fmt.Println(md5sum)
}

练习

编写md5sum程序

切片

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package main

import "fmt"

func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}
	
	var s []int = primes[1:4]
	fmt.Println(s)
}

slice.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
	primes := [6]int{2, 3, 5, 7, 11, 13}
	var s []int = primes[1:4]
	fmt.Println(s)
	fmt.Println(&s[0])
	fmt.Println(&primes[1])
	var s1 []int
	s1 = s
	fmt.Println(&s1[0] == &s[0])
}

切片原理

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

func main() {
	names := [4]string{
		"John",
		"Paul",
		"George",
		"Ringo",
	}
	fmt.Println(names)
	
	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)
	
	b[0] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
}

slice1.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import "fmt"

func main() {
	names := [4]string{
		"a",
		"b",
		"c",
		"d",
	}

	a := names[0:2]
	b := names[1:3]
	fmt.Println(a, b)

	/*
		                b = names[1:3]
				start := &names[1]

				p := start + 1
				*p = "XXX"
		                等价于
		                b[1] = "XXX"
	*/

	b[1] = "XXX"
	fmt.Println(a, b)
	fmt.Println(names)
	c := a[1:2]
	c[0] = "YYY"

	var p [2]*string
	p[0] = &names[0]
	p[1] = &names[1]
	*p[0] = "AAA"

	/*
		var start *string
		var length int
		//var cap int
		start = &names[1]
		length = 2
		start + 0 => b[0]
		start + 1 => b[1]
	*/

}

slice2.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

func main() {
	a := [...]int{2, 3, 5, 7, 11, 13}
	s := a[:0]
	fmt.Println(s, len(s), cap(s))
	s = s[:4]
	fmt.Println(s, len(s), cap(s))
	s = s[2:]
	fmt.Println(s, len(s), cap(s))
	var s1 []int
	if s1 == nil {
		fmt.Println("nil")
	}
	fmt.Println(len(s1))
	s1 = a[:0]
	fmt.Println(s1 == nil)

	a = []int{0, 0, 0, 0, 0}
	make([]int, 5)
}

作业1提示

练习

  • 反转切片的函数

str.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package main

import "fmt"

func main() {
	s := "a"
	fmt.Println(&s)
	s = s + "b"
	fmt.Println(&s)
}

append.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

func main() {
	s := make([]int, 0, 1)
	fmt.Println(len(s), cap(s))
	s = append(s, 1)
	fmt.Println(s)
	s = append(s, 2, 3, 4)
	fmt.Println(s)

	s1 := []int{13, 14, 15}
	s = append(s, s1...)
	fmt.Println(s)
	s2 := []int{2, 3, 5, 7, 11}
	fmt.Println(s2)

	// 11, 7, 5, 3, 2
	// 5 7 11 2 3
	// 3 2 11 7 5
	// 5 7 11 2 3
}

reverse.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import "fmt"

// 翻转切片
func reverse(s []int) {

}

func main() {
	s := []int{2, 3, 5, 7, 11}
	reverse(s)
	fmt.Println(s)
	reverse(s[1:4])
	fmt.Println(s)
}

rune.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package main

import "fmt"

func main() {
	// byte => uint8
	// rune => int32
	s := "golang你好"
	fmt.Println(len(s))
	cnt := 0
	for _, r := range s {
		cnt += 1
		fmt.Printf("%c\n", r)
	}
	ss := []rune("hello")
	fmt.Println(ss)

	fmt.Println("cnt", cnt)
}

map

map.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
	m := map[string]int{
		"a": 1,
	}
	fmt.Println(m["a"])
	delete(m, "a")
	fmt.Println(m["a"])

	var m1 map[string]int
	fmt.Println(m1 == nil)
	m1 = make(map[string]int)
}

统计词频

练习

统计单词出现的个数

split.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
)

func main() {
	content, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}

	count := make(map[string]int)
	words := strings.Fields(string(content))
	for _, word := range words {
		if word存在于count {
			count里面对应的word的value加1
		} else {
			置count里面对应的word的value为初值1
		}
	}

	for word, cnt := range count {
		fmt.Println(word, cnt)
	}
}

结构体

struct.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

type Student struct {
	Id   int
	Name string
}

func main() {
	var s Student
	s.Id = 1
	var b []byte

	// byte => uint8
	// rune => uint32
	var arr [3]Student
	var ss []Student
	var m map[string]Student
}

序列化和反序列化

练习

编写学生管理系统

  • list指令,列出所有的学生信息
  • add指令,增加一个学生信息

fmt.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
	"bufio"
	"fmt"
	"os"
)

type Student struct {
	Id   int
	Name string
}

func main() {
	var cmd string
	var name string
	var id int
	var line string
	f := bufio.NewReader(os.Stdin)

	//var students map[string]Student
	for {
		fmt.Print("> ")
		line, _ = f.ReadString('\n')
		fmt.Sscan(line, &cmd)
		switch cmd {
		case "list":
			fmt.Printf("binggan 01\njack 02\n")
		case "add":
			fmt.Sscan(line, &cmd, &name, &id)
			fmt.Printf("add done.\n")
		}
	}
}

序列化JSON

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
	"encoding/json"
	"fmt"
	"log"
)

type Student struct {
	Id int
	Name string
}

func main() {
	s := Student{
		Id: 2,
		Name: "alice",
	}
	buf, err := json.Marshal(s)
	if err != nil {
		log.Fatal("marshal error:%s", err)
	}
	fmt.Println(string(buf))
}

练习

将Student map的数据写入到文件

反序列化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
	"encoding/json"
	"fmt"
	"log"
)

type Student struct {
	Id int
	Name string
}

func main() {
	str := `{"Id":2,"Name":"alice"}`
	var s Student
	err := json.Unmarshal([]byte(str), &s)
	if err != nil {
		log.Fatal("unmarshal error:%s", err)
	}
	fmt.Println(s)
}

作业2

  • 增加save和load指令

练习

从文件中读取Student map的数据

qa

homework

完成切片旋转

指定一个切片的截断长度,旋转截断后的两个切片的位置

如切片为[2, 3, 5, 7, 11],长度为2,则旋转后的切片为[5, 7, 11, 2, 3]

完成切片旋转的同学可以尝试旋转单词,如hello world旋转为world hello

完成学生信息管理系统

实现如下4个指令

  1. add name id,添加一个学生的信息,如果name有重复,报错
  2. list, 列出所有的学生信息
  3. save filename,保存所有的学生信息到filename指定的文件中
  4. load filename, 从filename指定的文件中加载学生信息

框架代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
	"bufio"
	"fmt"
	"os"
)

type Student struct {
	Id   int
	Name string
}

func main() {
	var cmd string
	var name string
	var id int
	var line string
	f := bufio.NewReader(os.Stdin)

	//var students map[string]Student
	for {
		fmt.Print("> ")
		line, _ = f.ReadString('\n')
		fmt.Sscan(line, &cmd)
		switch cmd {
		case "list":
			fmt.Printf("binggan 01\njack 02\n")
		case "add":
			fmt.Sscan(line, &cmd, &name, &id)
			fmt.Printf("add done.\n")
		}
	}
}