GoStudy 练习
< 返回列表时间: 2020-07-17来源:OSCHINA
1.有一堆数字,如果除了一个数字以外,其他数字都出现了两次,那么如何找到出现一次的数字?
解法1: var arr = [...]int{1, 2, 3, 4, 5, 4, 2, 1, 5, 2, 1} var tmp = make([]int, len(arr), len(arr)) for _, v := range arr { tmp[v]++; } for k, v := range a22 { if v == 1 { fmt.Println(k,v) } }
解法2: package main import "fmt" func main() { nums := [...]int{1, 1, 2, 2, 3, 4, 4} res := 0 for _, v := range nums { res ^= v } fmt.Println(res) } 任何数和 00 做异或运算,结果仍然是原来的数,即 a ^ 0=aa⊕0=a。s 任何数和其自身做异或运算,结果是 00,即 a ^ a=0a⊕a=0。 异或运算满足交换律和结合律,即 a ^ b ^ a=b ^ a ^ a=b ^ (a ^ a)=b ^ 0=ba⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b。
2.编写代码统计出字符串 "学习go语言" 中汉字的数量。
解法1: package main import ( "fmt" ) func main() { str := "学习go语言" var count int ch := []rune(str) for _, v := range ch { if v > 256 { // ASCII码0-255 count++ fmt.Println(string(v)) } //if len(string(v)) >= 3 { //UTF8编码下一个中文汉字由3~4个字节组成 // count++ //} } fmt.Println(count) }
解法2: package main import ( "fmt" ) func main() { str := "学习go语言" count := 0 const startCode = 0x2E80 // ^[⺀-鿿]+$ 中日韩文字的正则表达式 const endCode = 0x9FFF for _, v := range str { if startCode < v && endCode > v { count++ fmt.Println(string(v)) } } fmt.Println(count) } 非英文汉字范围:https://www.cnblogs.com/yunsicai/p/4110522.html
if条件判断 func ifDemo1() { score := 65 if score >= 90 { fmt.Println("A") } else if score > 75 { fmt.Println("B") } else { fmt.Println("C") } } func ifDemo2() { if score := 65; score >= 90 { fmt.Println("A") } else if score > 75 { fmt.Println("B") } else { fmt.Println("C") } } 先执行score := 65这一条语句,再根据这个变量值进行判断,它的好处是语句执行完了这个变量就销毁了,对程序来说可以节约程序开销。
3 数组
1 求数组 [1, 3, 5, 7, 8] 所有元素的和
2 找出数组中和为指定值的两个元素的下标,比如从数组 [1, 3, 5, 7, 8] 中找出和为8的两个元素的下标分别为 (0,3) 和 (1,2) 。 //求数组[1, 3, 5, 7, 8]所有元素的和 func Sum() { a := [5]int{1, 3, 5, 7, 8} sum := 0 for _, i := range a { sum += i } fmt.Println(sum) } //找出数组中和为指定值的两个元素的下标,比如从数组[1, 3, 5, 7, 8]中找出和为8的两个元素的下标分别为(0,3)和(1,2)。 func Find() { a := [5]int{1, 3, 5, 7, 8} for i, j := range a { for l, k := range a[i+1:] { if j + k == 8 { fmt.Printf("(%d, %d) ", i, l+i+1) } } } } var num = [...]int{1, 3, 5, 7, 8} for _, value := range num { for i := 0; i < len(num)/2; i++ { // 1/2(O*n3) if value + num[i] == 8 { fmt.Println(value, num[i]) } } }
4.请使用内置的 sort 包对数组 var a = [...]int{3, 7, 8, 9, 1} 进行排序 package main import ( "fmt" "sort" ) func main() { var a = [...]int{3, 7, 8, 9, 1} b := a[:] sort.Ints(b) fmt.Println(b) sort.Sort(sort.Reverse(sort.IntSlice(b))) fmt.Println(b) }
5 map
1 写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。
2 观察下面代码,写出最终的打印结果。 1. package main import ( "fmt" "strings" ) func wordCount(words string) map[string]int { wordsStr := strings.Split(words, " ") m := make(map[string]int, len(wordsStr)) for _, word := range wordsStr { m[word]++ } return m } //func wordCount(words string) (m map[string]int) { 给返回值命名 // wordsStr := strings.Split(words, " ") // m = make(map[string]int, len(wordsStr)) // for _, word := range wordsStr { // m[word]++ // } // return //} func main() { var str = "how do you do" //fmt.Println(wordCount(str)) for k, v := range wordCount(str) { fmt.Println(k, v) } } 2. package main import ( "fmt" ) func main() { type Map map[string][]int m := make(Map) s := []int{1, 2} s = append(s, 3) fmt.Printf("%+v\n", s) m["why"] = s fmt.Printf("%+v\n", m["why"]) s = append(s[:1], s[2:]...) fmt.Printf("%+v\n", s) fmt.Printf("%+v\n", m["why"]) } [1 2 3] [1 2 3] [1 3] [1 3 3] 3???
6 分金币 /* 你有50枚金币,需要分配给以下几个人:Matthew,Sarah,Augustus,Heidi,Emilie,Peter,Giana,Adriano,Aaron,Elizabeth。 分配规则如下: a. 名字中每包含1个'e'或'E'分1枚金币 b. 名字中每包含1个'i'或'I'分2枚金币 c. 名字中每包含1个'o'或'O'分3枚金币 d: 名字中每包含1个'u'或'U'分4枚金币 写一个程序,计算每个用户分到多少金币,以及最后剩余多少金币? 程序结构如下,请实现 ‘dispatchCoin’ 函数 */ var ( coins = 50 users = []string{ "Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth", } distribution = make(map[string]int, len(users)) ) func main() { left := dispatchCoin() fmt.Println("剩下:", left) } package main import ( "fmt" "strings" ) var ( coins = 50 users = []string{ "Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth", } distribution = make(map[string]int, len(users)) ) func main() { left := dispatchCoin() fmt.Println("剩下:", left) } func dispatchCoin() (left int) { for _, name := range users { coin := countCoin(name) distribution[name] = coin fmt.Printf("%s 的金币为:%d\n", name, coin) } result := 0 for _, value := range distribution { result += value } fmt.Printf("总使用的金币: %d\n", result) return coins - result } func countCoin(name string) (result int) { if &name != nil { name = strings.ToUpper(name) bs := []byte(name) result = 0 for _, value := range bs { if value == 'E' { result++ } else if value == 'I' { result += 2 } else if value == 'O' { result += 3 } else if value == 'U' { result += 4 } } return } return 0 } //------------------------ func dispatchCoin() int { left := coins for _, name := range users { e := strings.Count(name, "e") + strings.Count(name, "E") i := strings.Count(name, "i") + strings.Count(name, "I") o := strings.Count(name, "o") + strings.Count(name, "O") u := strings.Count(name, "u") + strings.Count(name, "U") sum := e*1 + i*2 + o*3 + u*4 distribution[name] = sum left -= sum } fmt.Println(distribution) return left }
7 去重
1 slice&map package main import ( "fmt" ) func RemoveRepByLoop(slc []int) []int{ var result []int for i := range slc { flag := false for j := range result { if slc[i] == result[j] { flag = true break } } if !flag { result = append(result, slc[i]) } } return result } func RemoveRepByMap(slc []int) []int { var result []int tempMap := map[int]byte{} // 存放不重复主键 for _, e := range slc { l := len(tempMap) tempMap[e] = 0 if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复 result = append(result, e) } } return result } func removeDuplicateElement(arr []string) []string { result := make([]string, 0, len(arr)) temp := map[string]struct{}{} for _, item := range arr { if _, ok := temp[item]; !ok { temp[item] = struct{}{} result = append(result, item) } } return result } // 元素去重 func RemoveRep(slc []int) []int{ if len(slc) < 1024 { // 切片长度小于1024的时候,循环来过滤 return RemoveRepByLoop(slc) } else { // 大于的时候,通过map来过滤 return RemoveRepByMap(slc) } } func main() { arr := []int{6, 3, 5, 4, 3, 2, 1} s := []string{"golang", "python", "golang", "JavaScript", "python"} fmt.Println(RemoveRep(arr)) fmt.Println(removeDuplicateElement(s)) }
2 结构体 // setting_string.go setting_int.go string->int package utils import ( "sort" "sync" ) // 实现 set 集合,变相实现 切片去重 type StringSet struct { m map[string]bool sync.RWMutex } func NewStringSet() *StringSet { return &StringSet{ m: map[string]bool{}, } } func (s *StringSet) Add(items ...string) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { s.m[item] = true } } func (s *StringSet) Remove(items ...string) { s.Lock() defer s.Unlock() if len(items) == 0 { return } for _, item := range items { delete(s.m, item) } } func (s *StringSet) Has(item string) bool { s.RLock() defer s.RUnlock() _, ok := s.m[item] return ok } func (s *StringSet) Len() int { return len(s.List()) } func (s *StringSet) Clear() { s.Lock() defer s.Unlock() s.m = map[string]bool{} } func (s *StringSet) IsEmpty() bool { if s.Len() == 0 { return true } return false } func (s *StringSet) List() []string { s.RLock() defer s.RUnlock() var list []string for item := range s.m { list = append(list, item) } return list } func (s *StringSet) SortList() []string { s.RLock() defer s.RUnlock() var list []string for item := range s.m { list = append(list, item) } sort.Strings(list) return list } //main.go package main import ( "fmt" "goTest/utils" ) func main() { // int 集合 //s := utils.NewIntSet() // 添加数据 //s.Add(5, 2, 4, 3, 5, 6, 7) // 去重后的值 //fmt.Println(s.List()) // 排序后的值 //fmt.Println(s.SortList()) // string 集合 s2 := utils.NewStringSet() // 添加数据 s2.Add("goland", "python", "study", "goalng", "python", "goland") // 去重后的值 fmt.Println(s2.List()) // 排序后的值 fmt.Println(s2.SortList()) }
8 (结构体)使用“面向对象”的思维方式编写一个学生信息管理系统。
1.学生有id、姓名、年龄、分数等信息
2.程序提供展示学生列表、添加学生、编辑学生信息、删除学生等功能 package main import ( "fmt" "os" "sort" ) type Student struct { ID int Name string Age int8 Score int8 } type Class struct { Map map[int]*Student } //添加学生 func (c *Class) AddStudent() { var id int var name string var age int8 var score int8 fmt.Print("输入id: ") _, err := fmt.Scan(&id) fmt.Print("输入姓名: ") _, err = fmt.Scan(&name) fmt.Print("输入年龄: ") _, err = fmt.Scan(&age) fmt.Print("输入分数: ") _, err = fmt.Scan(&score) if err != nil { fmt.Println("保存出错!") } _, isSave := c.Map[id] if isSave { fmt.Println("学生ID已存在!") return } student := &Student{ ID: id, Name: name, Age: age, Score: score, } c.Map[id] = student fmt.Println("保存成功!") } //查看学生列表 func (c *Class) ShowStudent() { fmt.Printf("\t%s\t%s\t%s\t%s\n", "ID", "姓名", "年龄", "分数") sortID := make([]int, 0) for k := range c.Map { sortID = append(sortID, k) } sort.Ints(sortID) for _, k := range sortID { s := c.Map[k] fmt.Printf("\t%d\t%s\t%d\t%d\n", s.ID, s.Name, s.Age, s.Score) } } //删除学生 func (c *Class) DeleteStudent() { fmt.Print("输入要删除的学生ID:") var id int _, err := fmt.Scan(&id) if err != nil { fmt.Println("ID错误") } _, isSave := c.Map[id] if !isSave { fmt.Println("ID不存在!") } delete(c.Map, id) fmt.Println("删除成功!!") } //修改学生信息 func (c *Class) ChangeStudent() { fmt.Print("输入要修改的学生ID:") var id int _, err := fmt.Scan(&id) if err != nil { fmt.Println("ID错误") } var name string var age int8 var score int8 fmt.Print("输入姓名: ") _, err = fmt.Scan(&name) fmt.Print("输入年龄: ") _, err = fmt.Scan(&age) fmt.Print("输入分数: ") _, err = fmt.Scan(&score) if err != nil { fmt.Println("出错了!") } student := &Student{ ID: id, Name: name, Age: age, Score: score, } c.Map[id] = student fmt.Println("修改成功!") } func main() { c := &Class{} c.Map = make(map[int]*Student, 50) for { fmt.Print("1. 添加 2.查看 3.修改 4.删除 0. 退出\n") var todo int8 _, err := fmt.Scan(&todo) if err != nil { fmt.Println("输入有误!") } switch todo { case 1: c.AddStudent() case 2: c.ShowStudent() case 3: c.ChangeStudent() case 4: c.DeleteStudent() case 0: os.Exit(-1) default: fmt.Println("输入有误!") } } }
9 接口
使用接口的方式实现一个既可以往终端写日志也可以往文件写日志的简易日志库。 package main import ( "fmt" "io" "os" ) type Logger interface { Info(string) } type FileLogger struct { filename string } type ConsoleLogger struct {} /*func (fl *FileLogger) Info(msg string) { var f *os.File var err error if _, err = os.Stat(fl.filename); !os.IsNotExist(err) { f, err = os.OpenFile(fl.filename, os.O_APPEND|os.O_WRONLY, 0666) fmt.Println("open file!") } else { f, err = os.Create(fl.filename) if err != nil { panic(err) } fmt.Println("create file!") } defer f.Close() n, err := io.WriteString(f, msg + "\n") if err != nil { panic(err) } fmt.Printf("写入%d个字节\n", n) }*/ func (fl *FileLogger) Info(msg string) { var f *os.File var err error if checkFileIsExist(fl.filename) { f, err = os.OpenFile(fl.filename, os.O_APPEND|os.O_WRONLY, 0666) fmt.Println("File Exist!") } else { f, err = os.Create(fl.filename) fmt.Println("File Not Exist!") } defer f.Close() n, err := io.WriteString(f, msg + "\n") if err != nil { panic(err) } fmt.Printf("写入%d个字节\n", n) } func checkFileIsExist(filename string) bool { if _, err := os.Stat(filename); os.IsNotExist(err) { return false } return true } func (cl *ConsoleLogger) Info(msg string) { fmt.Println(msg) } func main() { var logger Logger fileLogger := &FileLogger{"log.txt"} logger = fileLogger logger.Info("Hello") logger.Info("study golang") consoleLogger := &ConsoleLogger{} logger = consoleLogger logger.Info("Hello!") logger.Info("study golang!") } --------------------------------------------------------------------------- type logSystem interface { console(interface{}) file(interface{}) } type localLog struct{} func (l localLog) console(log interface{}) { logInfo := log.(string) + "\n" _, _ = os.Stdout.WriteString(logInfo) } func (l localLog) file(log interface{}) { logMsg := log.(string) + "\n" filename := "interface.log" _, err := os.Stat(filename) if err != nil { fmt.Println("文件不存在!需要创建!") _, err := os.Create(filename) if err != nil { panic(err) } // fmt.Println(err) file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_EXCL, 0664) //|os.O_CREATE|os.O_EXCL if err != nil { // fmt.Println(err) fmt.Printf("创建打开文件,报错:%s", err) } defer file.Close() if _, err := file.WriteString(logMsg); err == nil { fmt.Println("写入文件成功!") } else { // fmt.Println("文件写入报错!") // fmt.Println(err) fmt.Printf("文件写入报错!,报错信息:%s", err) } } else { fmt.Println("文件存在!") // fmt.Println(fileStat) file, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 066) //|os.O_CREATE|os.O_EXCL if err != nil { fmt.Printf("打开文件错误,报错:%s", err) } defer file.Close() if _, err := file.WriteString(logMsg); err == nil { fmt.Println("写入文件成功!") } else { fmt.Println("文件写入报错!") fmt.Println(err) } } } func logger(log string) { // log := log var logger logSystem var application = localLog{} logger = application logger.console(log) logger.file(log) } func main() { var word string = "study golang!" logger(word) }
10 反射
编写代码利用反射实现一个ini文件的解析器程序。 pass
热门排行