[日常] Go语言圣经-Slice切片习题
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已,slice的底层确实引用一个数组对象
2.内置的len和cap函数分别返回slice的长度和容量
3.s[i:j] , 从第i个元素开始到第j-1个元素的子序列,s[:]切片操作则是引用整个数组
4.slice值包含指向第一个slice元素的指针,因此向函数传递slice将允许在函数内部修改底层数组的元素
5.将slice元素循环向左旋转n个元素的方法是三次调用reverse反转函数,第一次是反转开头的n个元素,然后是反转剩下的元素,最后是反转整个slice的元素。
6.slice之间不能比较,因此我们不能使用==操作符来判断两个slice是否含有全部相等元素,slice唯一合法的比较操作是和nil比较
7.可以用[]int(nil)类型转换表达式来生成一个对应类型slice的nil值
8.测试一个slice是否是空的,使用len(s) == 0来判断
9.make函数创建一个指定元素类型、长度和容量的slice , make([]T, len)
10.内置的append函数用于向slice追加元素
11.[]rune("Hello, 世界") 字符串转rune类型的slice
12.我们并不知道append调用是否导致了内存的重新分配,因此我们也不能确认新的slice和原始的slice是否引用的是相同的底层数组空间,通常是将append返回的结果直接赋值给输入的slice变量
13.函数参数中的最后的“...”省略号表示接收变长的参数为slice,func appendInt(x []int, y ...int) []int {}
14.报错invalid indirect of s[j] (type int) ,使用数组指针的时候(*s)[0]
15.Slice内存技巧,
练习 4.3: 重写reverse函数,使用数组指针代替slice。
练习 4.4: 编写一个rotate函数,通过一次循环完成旋转。
练习 4.5: 写一个函数在原地完成消除[]string中相邻重复的字符串的操作。
练习 4.6: 编写一个函数,原地将一个UTF-8编码的[]byte类型的slice中相邻的空格(参考unicode.IsSpace)替换成一个空格返回
练习 4.7: 修改reverse函数用于原地反转UTF-8编码的[]byte。是否可以不用分配额外的内存?
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | package main import ( "fmt" "unicode" ) func main(){ testArr := [5]int{0,1,2,3,4} //reverse(&testArr) fmt.Println(testArr) a:=rotate(testArr[:],2) fmt.Println(a) b:=[]string{ "tao" , "taoshihan" , "shi" , "shi" , "han" } emptyString(b) d:=[]byte( "abc bcd wer sdsd taoshihan de" ) e:=emptyString2(d) fmt.Println(string(e)) f:=[]byte( "abc bcd wer sdsd taoshihan de" ) reverse1(f) fmt.Println(string(f)) } /* 练习 4.3: 重写reverse函数,使用数组指针代替slice。 */ func reverse(s *[5]int){ i,j := 0,len(*s)-1; for i<j{ (*s)[i],(*s)[j]=(*s)[j],(*s)[i] i+=1 j-=1 } } /* 练习 4.4: 编写一个rotate函数,通过一次循环完成旋转。 */ func rotate(s []int,r int)[]int{ lens := len(s) //创建一个空的指定长度的slice res :=make([]int, lens) for i:=0 ;i<lens;i++{ index := i+r if index>=lens{ index=index-lens } res[i] = s[index] } return res } /* 练习 4.5:写一个函数在原地完成消除[]string中相邻重复的字符串的操作。 */ func emptyString(s []string)[]string{ i:=0 index:=0 num := len(s) for _,v := range s{ index =i+1 if index>=num{ break } if v != s[index]{ s[i]=v i++ } } fmt.Println(s[:i]) return s[:i] } /* 练习 4.6: 编写一个函数,原地将一个UTF-8编码的[]byte类型的slice中相邻的空格(参考unicode.IsSpace)替换成一个空格返回 */ func emptyString2(s []byte)[]byte{ index:=0 num := len(s) for i:=0;i<num;i++{ index =i+1 num = len(s) if index>=num{ break } if unicode.IsSpace(rune(s[i])) && unicode.IsSpace(rune(s[index])){ //结合remove函数 copy(s[i:],s[index:]) s=s[:len(s)-1] i-- } } return s } /* 练习 4.7: 修改reverse函数用于原地反转UTF-8编码的[]byte。是否可以不用分配额外的内存? */ func reverse1(s []byte) { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2017-04-11 [Linux] PHP程序员玩转Linux系列-使用supervisor实现守护进程
2016-04-11 [android] 手机卫士手势滑动切换屏幕
2016-04-11 [android] 手机卫士界面切换动画