Maps

什么是 map ?

  类似Python中的字典数据类型,以k:v键值对的形式。

  map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值。

如何创建 map ?

  通过向 make 函数传入键和值的类型,可以创建 map。make(map[type of key]type of value) 是创建 map 的语法。

  1. // personSalary := make(map[string]int)

  上面的代码创建了一个名为 personSalary 的 map,其中键是 string 类型,而值是 int 类型。

map 的零值是 nil。如果你想添加元素到 nil map 中,会触发运行时 panic。因此 map 必须使用 make 函数初始化。

  1. //maps
  2. package main
  3.  
  4. import "fmt"
  5.  
  6. func main() {
  7. //maps的定义
  8. //map的key值必须可hash
  9. //var a map[键值类型]value值类型
  10. //map的空值是nil类型
  11. var a map[int]string
  12. fmt.Println(a)
  13. if a==nil{
  14. fmt.Println("xxxx")
  15. }
  16. }

map修改和添加元素

  给 map 添加新元素的语法和数组相同

  1. package main
  2. import "fmt"
  3. func main(){
  4.  
  5. //map的赋值跟取值
  6. //map的初始化
  7. var a map[int]string=make(map[int]string)
  8. fmt.Println(a)
  9. if a==nil{
  10. fmt.Println("hello")
  11. }
  12.  
  13. a[1]="100"
  14. a[2]="888"
  15. fmt.Println(a)
  16. fmt.Println(a[1])
  17.  
  18. ////取一个不存在的key值会?返回value值的空值
      ////fmt.Println(a[9])
  19. //var b map[int]int=make(map[int]int)
  20. //b[1]=100
  21. //fmt.Println(b)
  22. ////fmt.Println(b[9])
  23. //if v,ok:=a[9];ok{
  24. // fmt.Println("=-====",v)
  25. //}else {
  26. // fmt.Println("该值不存在")
  27. //}
  28. //v,ok:=a[1]
  29. //fmt.Println(v)
  30. //fmt.Println(ok)
  31.  
  32. //定义和初始化的第二种方式
  33. //var a =map[int]string{1:"10",2:"100"}
  34. ////a[1]
  35. //fmt.Println(a[1])
  36. }

对应的以key:value的形式赋值,赋值和取值都是通过key来操作value的。

删除 map 中的元素

  删除 map 中 key 的语法是 [delete(map, key)]。这个函数没有返回值。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("map before deletion", personSalary)
  14. delete(personSalary, "steve")
  15. fmt.Println("map after deletion", personSalary)
  16.  
  17. }

上述程序删除了键 "steve",输出:

  1. map before deletion map[steve:12000 jamie:15000 mike:9000]
  2. map after deletion map[mike:9000 jamie:15000]

获取 map 的长度

  获取 map 的长度使用 [len]函数。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. personSalary := map[string]int{
  9. "steve": 12000,
  10. "jamie": 15000,
  11. }
  12. personSalary["mike"] = 9000
  13. fmt.Println("length is", len(personSalary))
  14.  
  15. }

上述程序中的 len(personSalary) 函数获取了 map 的长度。程序输出 length is 3。3对k:v键值对。

Map 是引用类型

  和 [slices]类似,map 也是引用类型。当 map 被赋值为一个新变量的时候,它们指向同一个内部数据结构。因此,改变其中一个变量,就会影响到另一变量。

  1. package main
  2. import "fmt"
  3. func main(){
  4. //Map 是引用类型
  5. var a =map[int]string{1:"10",2:"100"}
  6. test4(a)
  7. fmt.Println(a)
  8. func test4(a map[int]string) {
  9. a[1]="888"
  10. fmt.Println(a)
  11.  
  12. }

当 map 作为函数参数传递时也会发生同样的情况。函数中对 map 的任何修改,对于外部的调用都是可见的。

Map 的相等性

  map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil

  1. package main
  2. import "fmt"
  3. func main(){
  4.  
  5. //Map 的相等性
  6. map1 := map[string]int{
  7. "one": 1,
  8. "two": 2,
  9. }
  10.  
  11. map2 := map1
  12.  
  13. if map1 == map2 { //报错
  14. }
  15.  
  16. //map循环出所有元素
  17. //var a =map[int]string{1:"10",0:"100",10:"999"}
  18. ////for i:=0;i<len(a);i++{
  19. //// fmt.Println(a[i])
  20. ////}
  21. ////map是无序的
  22. //for k,v:=range a{
  23. // fmt.Println(k)
  24. // fmt.Println(v)
  25. //}
  26.  
  27. //补充:切片删除元素
  28. //var a =[]int{1,2,3,4,5,6}
  29. //a=append(a[0:2],a[3:]...)
  30. //fmt.Println(a)
  31. }
  32.  
  33. }

上面程序抛出编译错误 invalid operation: map1 == map2 (map can only be compared to nil)

判断两个 map 是否相等的方法是遍历比较两个 map 中的每个元素。我建议你写一段这样的程序实现这个功能

字符串

什么是字符串?

  Go 语言中的字符串是一个字节切片。把内容放在双引号" "之间,我们可以创建一个字符串。让我们来看一个创建并打印字符串的简单示例。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func main() {
  8. name := "Hello World"
  9. fmt.Println(name)
  10. }

上面的程序将会输出 Hello World

Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。

其他方法:

  1. package main
  2. import (
  3. "fmt"
  4. "unicode/utf8"
  5. )
  6. package main
  7.  
  8. import (
  9. "fmt"
  10. "unicode/utf8"
  11. )
  12. func main() {
  13.  
  14. name := "Hello World蟒蛇"
  15. //name:="赵"
  16. //字符串长度,len统计字节数
  17. //在go种string类型都是utf-8编码
  18.  
  19. fmt.Println(len(name))
  20. fmt.Println(utf8.RuneCountInString(name))
  21. //unicode是一个字符编码对照表
  22.  
  23. //循环
  24. //字符串是个只读切片
  25. //name := "name赵"
  26. //for i:=0;i<len(name);i++{
  27. // fmt.Println(string(name[i]))
  28. // fmt.Printf("%T",name[i])
  29. // fmt.Println()
  30. //}
  31.  
  32. //for _,v:=range name{
  33. // fmt.Println(string(v))
  34. // fmt.Printf("%T",v)
  35. // fmt.Println()
  36. //}
  37.  
  38. //name := "name赵"
  39. //name[0]=99
  40. //fmt.Println(name[0])
  41. //fmt.Println(string(name[0]))
  42.  
  43. byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}// 打印的是字节数
  44. str := string(byteSlice)
  45. a:=len(str)
  46. b:=utf8.RuneCountInString(str)
  47. fmt.Println(b)
  48. fmt.Println(a)
  49. fmt.Println(str)
  50. }

需要注意的是:字节数和字符数的区别,一个字节占用了三个字符个数;取长度的关键字:-len(str)    utf8.RuneCountInString(str)

单独获取字符串的每一个字节

  由于字符串是一个字节切片,所以我们可以获取字符串的每一个字节。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. func printBytes(s string) {
  8. for i:= 0; i < len(s); i++ {
  9. fmt.Printf("%x ", s[i])
  10. }
  11. }
  12.  
  13. func main() {
  14. name := "Hello World"
  15. printBytes(name)
  16. }

go中的string字符串的形式都是以utf-8的形式存入内存中,而其他语言以Unicode万国码形式,获取长度用:

字符串的 for range 循环

  循环出来的是一个个的字符数,可以用rune的方法和for range的方法

  1. package main
  2. import "fmt"
  3. func main(){
  4.  
  5. //循环
  6. //字符串是个只读切片
  7. // 第一种:循环字节的个数
  8. name := "name赵"
  9. //for i:=0;i<len(name);i++{
  10. // fmt.Println(string(name[i]))
  11. // fmt.Printf("%T",name[i])
  12. // //fmt.Println()
  13. //}
  14. // 循环出来的字符的个数,一般用第二种,会乱码
  15. for _,v:=range name{
  16. fmt.Println(string(v)) //转格式
  17. fmt.Printf("%T",v)
  18. fmt.Println()
  19. }
  20. //字符串是个只读切片,只能读,不能等修改
  21. //name := "name赵"
  22. //name[0]=99
  23. fmt.Println(name[0])
  24. fmt.Println(string(name[0]))
  25.  
  26. }

字符串是不可变的,Go 中的字符串是不可变的。一旦一个字符串被创建,那么它将无法被修改

字符只能读取,不支持修改。

用字节切片构造字符串

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. "unicode/utf8"
  6. )
  7. func main() {
  8. byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}// 打印的是字节数
  9. str := string(byteSlice)
  10. a:=len(str)
  11. b:=utf8.RuneCountInString(str)
  12. fmt.Println(b)
  13. fmt.Println(a)
  14. fmt.Println(str)
  15. }

指针

什么是指针?

  指针是一种存储变量内存地址(Memory Address)的变量。

如上图所示,变量 b 的值为 156,而 b 的内存地址为 0x1040a124。变量 a 存储了 b 的地址。我们就称 a 指向了 b

指针的声明

指针变量的类型为 *T,该指针指向一个 T 类型的变量。

总结:

  1. //&取地址符号
  2. //* 放在类型旁边,表示指向这个类型的指针
  3. //* 放在变量旁边,表示解引用(反解)

例子:

  1. //指针
  2. package main
  3.  
  4. import "fmt"
  5. func main() {
  6. //&取地址符号
  7. //* 放在类型旁边,表示指向这个类型的指针
  8. //* 放在变量旁边,表示解引用(反解)
  9. a:=10
  10. //b就是一个指针 指向int类型的指针
  11. //b:=&a
  12. //d:="sss"
  13. //var c *string=&d
  14. var b *int =&a
  15. fmt.Println(b)
  16. fmt.Println(*b) //把b对应的值给取出来
  17. c:=&b
  18. //var c **int=&b //指向int类型的指针
  19. fmt.Println(*(*c))
  20. }

指针的零值(Zero Value)

指针的零值是 nil

  1. package main
  2. import "fmt"
  3. func main(){
  4. //指针的零值(Zero Value),nil类型
  5. //var a *int
  6. //fmt.Println(a)
  7. }>>>nil

向函数传递指针参数

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func change(val *int) {
  6. *val = 55
  7. }
  8. func main() {
  9. a:=58
  10. fmt.Println(a)
  11. b:=&a
  12. change(b)
  13. fmt.Println(a)
  14. }

在上面程序中的,我们向函数 change 传递了指针变量 b,而 b 存储了 a 的地址。程序在 change 函数内使用解引用。

不要向函数传递数组的指针,而应该使用切片

  假如我们想要在函数内修改一个数组,并希望调用函数的地方也能得到修改后的数组,一种解决方案是把一个指向数组的指针传递给这个函数。

  1. //向函数传递指针参数
  2. a := 10
  3. b := &a
  4. test6(b)
  5. fmt.Println(a)
  6. test7(a)
  7. fmt.Println(a)
  8.  
  9. //不要向函数传递数组的指针,而应该使用切片
  10. var a [100]int
  11. test9(&a)
  12. fmt.Println(a)
  13. test10(a[:])
  14. fmt.Println(a)
  15. //Go 不支持指针运算
  16.  
  17. func test9(a *[4]int) {
  18. (*a)[0]=999
  19. fmt.Println(a)
  20. }
  21. func test10(a []int) {
  22. a[0]=999
  23. fmt.Println(a)
  24.  
  25. }

只是不建议,可以使用,但系统默认会认为是指针的地址。

Go 不支持指针运算

  Go 并不支持其他语言(例如 C)中的指针运算。

  1. package main
  2. func main() {
  3. b := [...]int{109, 110, 111}
  4. p := &b
  5. p++
  6. }

上面的程序会抛出编译错误:main.go:6: invalid operation: p++ (non-numeric type *[3]int)

16. 结构体

什么是结构体?

  类似其他语言的面向对象,一个类有属性有方法;go中可以通过其他的方法实现类的三大属性:继承,封装,多态派生的方法。

  结构体是用户定义的类型,表示若干个字段(Field)的集合。有时应该把数据整合在一起,而不是让这些数据没有联系。这种情况下可以使用结构体。

例如,一个职员有 firstNamelastName 和 age 三个属性,而把这些属性组合在一个结构体 employee 中就很合理。

结构体的声明

格式:type 关键字 解构体名字 struct{ }

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. //结构体:是一系列属性的集合
  6. //定义一个人结构体
  7. //type关键字 结构体名字 struct{}
  8. type Person struct {
  9. name string
  10. sex int
  11. age int
  12.  
  13. }
  14.  
  15. func main() {
  16. //person :=Person{}
  17. //定义没有初始化
  18. //结构体是值类型
  19. //var person Person
  20. //var person Person=Person{name:"lqz"}
  21. var person Person=Person{"lqz",1,19}
  22. //person.name="lqz"
  23. fmt.Println(person.name) // 获取的话直接·属性
  24. }

创建匿名结构体

  匿名就是没有type的结构体名,但要引用的话必须先实例化才能使用,与一般的结构体有点区别而已。

  1. package main
  2. import "fmt"
  3. func main(){
  4. a:=struct {
  5. name string
  6. age int
  7. hobby string
  8. }{"rose",19,"music"}
  9. fmt.Printf(a.name)
  10. //fmt.Printf(a.age)
  11. fmt.Printf( a.hobby)
  12.  
  13. }

结构体的零值(Zero Value)

  当定义好的结构体并没有被显式地初始化时,该结构体的字段将默认赋为零值,有字段决定。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. type Employee struct {
  8. firstName, lastName string
  9. age, salary int
  10. }
  11.  
  12. func main() {
  13. var emp4 Employee //zero valued structure
  14. fmt.Println("Employee 4", emp4)
  15. }

该程序定义了 emp4,却没有初始化任何值。因此 firstName 和 lastName 赋值为 string 的零值("")。

而 age 和 salary 赋值为 int 的零值(0)。该程序会输出:

 
  1. Employee 4 { 0 0}

结构体的指针

  也可以创建指向结构体的指针。

  1. package main
  2. import "fmt"
  3. func main(){
  4. //结构体指针
  5. p:=Person{name:"lqz"}
  6. //pPoint:=&p
  7. var pPoint *Person=&p
  8. //fmt.Println(pPoint)
  9. //fmt.Println((*pPoint).name)
  10. fmt.Println(pPoint.name)
  11.  
  12. }

匿名字段

  当我们创建结构体时,字段可以只有类型,而没有字段名。这样的字段称为匿名字段

以下代码创建一个 Person 结构体,它含有两个匿名字段 string 和 int

  1. type Person struct {
  2. string
  3. int
  4. }

我们接下来使用匿名字段来编写一个程序。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. type Person struct {
  8. string
  9. int
  10. }
  11.  
  12. func main() {
  13. p := Person{"Naveen", 50}
  14. fmt.Println(p)
  15. }

  上述直接传相应的字段类型的值即可,会自动匹配字段类型。

虽然匿名字段没有名称,但其实匿名字段的名称就默认为它的类型

嵌套结构体(Nested Structs)

  字段定义的时候,字段里嵌套另一个字段。

  1. // 嵌套结构体
  2. package main
  3. import "fmt"
  4.  
  5. type Person struct{
  6.   name string
  7.   sex int
  8.   age int
  9.   hobby Hobby
  10.  
  11. }
  12.  
  13. type Hobby struct{
  14.   id int
  15.   name string
  16.  
  17. }
  18.  
  19. func main(){
  20.  
  21. //erson{name:"gai",hobby:Hobby{id:10,name:"篮球“} // 两种传参方式
  22. p:=Person{name:"lqz",hobby:Hobby{id:10,name:"篮球"}}
  23. p.hobby.id=102
  24.  
  25. fmt.PrintLn(P.hobby.name) // 获取属性值的方法
  26. }
  27.  
  28. }
  1. //变量提升过程中如果有重名的,就不提升了
    //p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}}
    //fmt.Println(p.Hobby.name)
    //fmt.Println(p.name)
  1. >>:篮球

提升字段(Promoted Fields)

有点类似面向对象的继承,继承类中的属性。

  如果是结构体中有匿名的结构体类型字段,则该匿名结构体里的字段就称为提升字段。这是因为提升字段就像是属于外部结构体一样,可以用外部结构体直接访问。

  1. type Address struct {
  2. city, state string
  3. }
  4. type Person struct {
  5. name string
  6. age int
  7. Address
  8. }

  在上面的代码片段中,Person 结构体有一个匿名字段 Address,而 Address 是一个结构体。

现在结构体 Address 有 city 和 state 两个字段,访问这两个字段就像在 Person 里直接声明的一样,因此我们称之为提升字段。

  1. package main
  2.  
  3. import (
  4. "fmt"
  5. )
  6.  
  7. type Address struct {
  8. city, state string
  9. }
  10. type Person struct {
  11. name string
  12. age int
  13. Address
  14. }
  15.  
  16. func main() {
  17. var p Person
  18. p.name = "Naveen"
  19. p.age = 50
  20. p.Address = Address{
  21. city: "Chicago",
  22. state: "Illinois",
  23. }
  24. fmt.Println("Name:", p.name)
  25. fmt.Println("Age:", p.age)
  26. fmt.Println("City:", p.city) //city is promoted field
  27. fmt.Println("State:", p.state) //state is promoted field
  28. }

在上面代码中的第 26 行和第 27 行,我们使用了语法 p.city 和 p.state,访问提升字段 city 和 state 就像它们是在结构体 p 中声明的一样。该程序会输出:

 
  1. Name: Naveen
  2. Age: 50
  3. City: Chicago
  4. State: Illinois

结构体相等性(Structs Equality)

  结构体是值类型。如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的

练习:

通过map为数组添加三个元素,执行代码map[0](9)得到9,map[1](9得到81,mapp[2](9)得到729.

  1. //-map内放函数
  2. //-通过map实现set
  3.  
  4. func main() {
  5. var m map[int]func(a int)int=make(map[int]func(a int)int)
  6. m[1]= func(a int) int {
  7.  
  8. return a
  9. }
  10. m[2]= func(a int) int {
  11. return a*a
  12. }
  13. m[3]= func(a int) int {
  14. return a*a*a
  15. }
  16.  
  17. fmt.Println(m[1](9))
  18. fmt.Println(m[2](9))
  19. fmt.Println(m[3](9))
  20. }

 

map 实现set类型,增加删除修改元素,判断元素是否存在,获取len 等

  1. func main() {
  2. //集合
  3. //可以放值,如果重复了,放不进去
  4. //可以获取长度
  5. //判断一个值是否在集合内
  6. //把集合内所有元素打印出来
  7.  
  8. var m map[string]bool=make(map[string]bool)
  9. m["lqz"]=true
  10. m["egon"]=true
  11.  
  12. m["lqz"]=true
  13.  
  14. fmt.Println(len(m))
  15. //"aa"是否在集合内
  16. if m["aa"]{
  17. fmt.Println("在里面")
  18. }else {
  19. fmt.Println("不再")
  20. }
  21. for k,_:=range m{
  22. fmt.Println(k)
  23. }
  24.  
  25. }
 
  1.  

Go-map-字符串-指针-结构体的更多相关文章

  1. Go-常识补充-切片-map(类似字典)-字符串-指针-结构体

    目录 Go 常识补充 Go 命名 打印变量类型科普 _ 关键字 命名规范相关 包目录规范 切片 多维切片 切片初始化的方法 多维切片初始化 切片删除元素(会略微影响效率 ,少用) copy 函数 打散 ...

  2. 【AT91SAM3S】SAM3S-EK Demo工程中,LCD驱动程序的加载(函数指针结构体)

    为了调试LCD,在英倍特的板子上烧Atmel的sam3s-ek_demo_1.4_source示例代码.LCD显示正常了,却找不到LCD的驱动究竟在哪. 花了好久,追踪到了这个执行过程. 进入main ...

  3. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  4. C学习笔记(5)--- 指针第二部分,字符串,结构体。

    1. 函数指针(function pointer): 函数指针是指向函数的指针变量. 通常我们说的指针变量是指向一个整型.字符型或数组等变量,而函数指针是指向函数. 函数指针可以像一般函数一样,用于调 ...

  5. go 学习 (三):函数 & 指针 & 结构体

    一.函数 函数声明 // 声明语法 func funcName (paramName paramType, ...) (returnType, returnType...) { // do somet ...

  6. 深入理解指针—>结构体里的成员数组和指针

    单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如 ...

  7. typedef struct 指针结构体使用方法

    A>>>>>>>>>>>>>>>>>>>>>>>> ty ...

  8. 【C++】结构体/结构体数组/结构体指针/结构体嵌套/函数参数/const

    一.结构体声明 struct Student { //成员列表 string name; int age; int score; }; //s3;定义时直接声明 int main() { struct ...

  9. Hihocoder #1014 : Trie树 (字典数树统计前缀的出现次数 *【模板】 基于指针结构体实现 )

    #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助, ...

随机推荐

  1. [APIO2012]派遣 可并堆

    Background 在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿. Description 在这个帮派里,有一名忍者被称之为Master.除了Master以外,每名忍者 ...

  2. ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布式集群搭建

    ubuntu18.04.2 hadoop3.1.2+zookeeper3.5.5高可用完全分布式集群搭建 集群规划: hostname NameNode DataNode JournalNode Re ...

  3. Python MongoDB 插入文档

    章节 Python MySQL 入门 Python MySQL 创建数据库 Python MySQL 创建表 Python MySQL 插入表 Python MySQL Select Python M ...

  4. 基础语法-选择结构switch

    基础语法-选择结构switch 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Switch语句特点 switch语句选择的类型在jdk1.6只支持四种:byte,short,i ...

  5. SQL的7种连接查询详细实例讲解

    SQL的7种连接查询详细实例讲解 原文链接:https://mp.weixin.qq.com/s/LZ6BoDhorW4cSBhaGy8VUQ 在使用数据库查询语句时,单表的查询有时候不能满足项目的业 ...

  6. tyvj 1860 后缀数组

    真·模板题(然而还是TLE了,tyvj真是个毒瘤,输出double什么的就是 -0.00000000,这些就TLE2333) 简单的说一下本蒟蒻看了一天后缀数组的收获(这东西太神了,,,wcwc,,收 ...

  7. java课程课后作业190530之找水王

    从题目中我们可以看出,水王有着相当严苛的条件才可以成为,那就是必须拥有一半的评论量才可以当上水王.当然这就是破题的关键,最简单的算法当然是用O(N平方)的复杂度的那种算法,但显然,我们需要的不是这种. ...

  8. Django2.0中的urlpattern匹配不输入任何网址时的写法

    如果使用urlpattern匹配不输入任何网址时,应该如何写? 例如:仅匹配http://127.0.0.1:8000/时想要跳转到某个页面,这时urlpattern中的url规则应该写成: 情况1: ...

  9. Android自定义View——贝塞尔曲线实现水波纹效果

    我们使用到的是Path类的quadTo(x1, y1, x2, y2)方法,属于二阶贝塞尔曲线,使用一张图来展示二阶贝塞尔曲线,这里的(x1,y1)是控制点,(x2,y2)是终止点,起始点默认是Pat ...

  10. 寒假day20

    今天解决了部分信息爬取不下来的问题