Go语言基础-02复合数据类型
课程内容
1流程控制补充 goto break+label continue+label
2数组: 声明(零值,类型),初始化,操作:
3切片: 声明(零值,类型),初始化,操作:
4map: 声明(零值,类型),初始化,操作:
5练习,字符统计 我有一个梦想
6字符串处理
7排序
8作业
001 流程控制补充
goto
D:\GoWork\src\code\day02\goto.go
package main
import "fmt"
func main() { total := 0 index := 0 max := 100 START: index += 1 total += index if index == max { goto END } goto START END: fmt.Println(total) } |
D:\GoWork\src\code\day02>go run goto.go 5050 |
break+lable 跳转
D:\GoWork\src\code\day02\break.go
package main
import "fmt"
func main() { BREAK: for z := 0; z < 2; z++ { fmt.Println(z, "*****")
for j := 0; j < 3; j++ { fmt.Println(j, "-----") for i := 0; i < 5; i++ { fmt.Println(i) if i == 3 { break BREAK } } } } } |
D:\GoWork\src\code\day02>go run break.go 0 ***** 0 ----- 0 1 2 3 |
package main
import "fmt"
func main() {
BREAK:
for z := 0; z < 2; z++ {
fmt.Println(z, "*********")
for j := 0; j < 3; j++ {
fmt.Println(j, "----")
for i := 0; i < 5; i++ {
fmt.Println(i)
if i == 3 {
break BREAK
}
}
}
}
}
continue+lable跳转
package main
import "fmt"
func main() { CONTINUE: for z := 0; z < 2; z++ { fmt.Println(z, "*****")
for j := 0; j < 3; j++ { fmt.Println(j, "-----") for i := 0; i < 5; i++ { fmt.Println(i) if i == 3 { continue CONTINUE } } } } } |
D:\GoWork\src\code\day02>go run continue.go 0 ***** 0 ----- 0 1 2 3 1 ***** 0 ----- 0 1 2 3 |
002 数组
学习顺序:
含义
声明(零值),类型
初始化
操作
声明
D:\GoWork\src\code\day02\array.go
package main
import "fmt"
func main() { var names [3]string var signIns [3]bool var scores [3]float64 //类型,零值 fmt.Printf("%T %#v\n", names, names) //[3]string [3]string{"", "", ""} fmt.Printf("%T %#v\n", signIns, signIns) //[3]bool [3]bool{false, false, false} fmt.Printf("%T %#v\n", scores, scores) //[3]float64 [3]float64{0, 0, 0} } |
初始化(3种方式)
//第一种,先声明再赋值(默认零值) //第二种 声明并赋值 //第三种 指定位置元素 |
D:\GoWork\src\code\day02\array1.go
package main
import "fmt"
func main() {
//初始化 //第一种,先声明再赋值(默认零值) var names [3]string names = [3]string{"语文", "数学", "英语"} // names = [1]string{"语文"} //报错和声明的类型不一致cannot use [1]string{…}
fmt.Println(names) //[语文 数学 英语] names = [...]string{"语文01", "数学01", "英语01"} fmt.Println(names) //[语文01 数学01 英语01]
//第二种 声明并赋值 testnames02 := [3]string{"语文02", "数学02", "英语02"} testnames03 := [...]string{"语文03", "数学03", "英语03"} fmt.Println(testnames02) //[语文02 数学02 英语02] fmt.Println(testnames03) //[语文03 数学03 英语03]
//第三种 指定位置元素 注意结果,不是修改 names = [3]string{1: "物理"} fmt.Printf("%#v\n", names) // [3]string{"", "物理", ""} } |
操作
关系运算
访问和修改
获取长度
遍历
D:\GoWork\src\code\day02\array2.go
package main
import "fmt"
func main() {
//关系运算 names := [3]string{"语文", "数学", "英语"} // var scores [3]float64 // fmt.Println(names==scores) //类型不一致,不能运算 fmt.Println(names == [3]string{"语文", "数学", "英语"})
// 访问&修改 fmt.Printf("%q\n", names[0]) names[0] = "化学" fmt.Printf("%#v\n", names)
// 获取len() fmt.Println(len(names))
//遍历 for i := 0; i < len(names); i++ { fmt.Println(names[i]) } for _, v := range names { fmt.Println(v) } } |
D:\GoWork\src\code\day02>go run array2.go true "语文" [3]string{"化学", "数学", "英语"} 3 化学 数学 英语 化学 数学 英语 |
二维数组
D:\GoWork\src\code\day02\array3.go
package main
import "fmt"
func main() { // 定义一个二维数组,每个元素也是数组 d2 := [3][2]int{0: [2]int{0, 1}, 1: [2]int{1, 2}, 2: [2]int{2, 3}}
//访问元素 fmt.Printf("%#v\n", d2) fmt.Println(d2[0]) fmt.Println(d2[0][1])
//修改元素 fmt.Println(d2) d2[1] = [2]int{10, 11} fmt.Println(d2) d2[1][0] = 11 fmt.Println(d2) }
|
/* D:\GoWork\src\code\day02>go run array3.go [3][2]int{[2]int{0, 1}, [2]int{1, 2}, [2]int{2, 3}} [0 1] 1 [[0 1] [1 2] [2 3]] [[0 1] [10 11] [2 3]] [[0 1] [11 11] [2 3]] */ |
第02天 下午01
003 切片
声明
D:\GoWork\src\code\day02\slice.go
package main
import "fmt"
func main() { var names []string fmt.Printf("%T %#v\n", names, names)
}
|
/* D:\GoWork\src\code\day02>go run slice.go []string []string(nil) */ |
初始化(3种方式)+make方式+数组或元素上切
先声明,再赋值 声明并赋值 指定位置元素 make 在数据或切片上切 |
D:\GoWork\src\code\day02\slice1.go
package main
import ( "fmt" )
func main() { // 初始化 // 第一种 先声明再赋值 var names []string names = []string{} names = []string{"语文", "数学", "英语"} fmt.Printf("%#v\n", names) // 第二种 声明并赋值 names1 := []string{"语文", "数学", "英语"} fmt.Printf("%#v\n", names1)
// 第三种 通过索引赋值 names2 := []string{1: "语文", 100: "数学"} fmt.Printf("%#v\n", names2)
// make方式 names3 := make([]string, 5) //申请有5个字符串元素的切片 fmt.Printf("%#v\n", names3) names4 := make([]string, 0, 10) fmt.Printf("%#v\n", names4)
// 从数组切 nums := [6]int{1, 2, 3, 4, 5, 6} numsSli := nums[2:5] fmt.Println(numsSli) } |
/* D:\GoWork\src\code\day02>go run slice1.go []string{"语文", "数学", "英语"} []string{"语文", "数学", "英语"} []string{"", "语文", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "数学"} []string{"", "", "", "", ""} []string{} [3 4 5] */ |
操作
访问和修改
获取长度和容量
遍历
D:\GoWork\src\code\day02\slice2.go
package main
import ( "fmt" )
func main() { // 访问和修改 names := make([]string, 3, 10) names[0] = "a" names[1] = "b" names[2] = "c" // names[3] = "d" // panic: runtime error: index out of range [3] with length 3 fmt.Println(names[0]) fmt.Println(names[1]) fmt.Println(names[2])
//获取长度和容量 fmt.Println(len(names), cap(names)) //3 10
//遍历 for i := 0; i < len(names); i++ { fmt.Println(names[i]) }
for i, v := range names { fmt.Println(i, v) } }
|
/* D:\GoWork\src\code\day02>go run slice2.go a b c 3 10 a b c 0 a 1 b 2 c */ |
append 添加元素
copy切片之间赋值
D:\GoWork\src\code\day02\slice3.go
package main
import "fmt"
func main() { //索引 names := make([]string, 3) names[0] = "a" names[1] = "b" names[2] = "c" //names[3]="d" //panic: runtime error: index out of range [3] with length 3 // 添加元素 names = append(names, "d") fmt.Printf("%#v\n", names) fmt.Println(len(names), cap(names))
// copy 切片之间的赋值 //长度相等 aSlice := []string{"a", "b", "c"} bSlice := []string{"x", "y", "z"} copy(aSlice, bSlice) fmt.Printf("%#v,%#v\n", aSlice, bSlice)
// 源多 aSlice = []string{"a", "b", "c"} bSlice = []string{"x", "y", "z", "m"} copy(aSlice, bSlice) fmt.Printf("%#v,%#v\n", aSlice, bSlice)
// 目标切片元素多
aSlice = []string{"a", "b", "c", "m"} bSlice = []string{"x", "y", "z"} copy(aSlice, bSlice) fmt.Printf("%#v,%#v\n", aSlice, bSlice)
} |
D:\GoWork\src\code\day02>go run slice3.go []string{"a", "b", "c", "d"} 4 6 []string{"x", "y", "z"},[]string{"x", "y", "z"} []string{"x", "y", "z"},[]string{"x", "y", "z", "m"} []string{"x", "y", "z", "m"},[]string{"x", "y", "z"} |
切片副作用及避免副作用
D:\GoWork\src\code\day02\slice4.go
package main
import "fmt"
func main() { // 切片副作用 nums := []int{0, 1, 2, 3, 4, 5} numsChildren := nums[3:4] numsChildren = append(numsChildren, 100) fmt.Println(nums, numsChildren) //[0 1 2 3 100 5] [3 100]
//避免: 创建新切片 nums = []int{0, 1, 2, 3, 4, 5} numsChildren = make([]int, len(nums[3:4])) copy(numsChildren, nums[3:4]) numsChildren = append(numsChildren, 100) fmt.Println(nums, numsChildren) //
//避免:指定结束位置, 再append切片 不会改原来切片,会生成新数组 nums = []int{0, 1, 2, 3, 4, 5} numsChildren = nums[3:4:4] numsChildren = append(numsChildren, 100) fmt.Println(nums, numsChildren) // } |
D:\GoWork\src\code\day02>go run slice4.go [0 1 2 3 100 5] [3 100] [0 1 2 3 4 5] [3 100] [0 1 2 3 4 5] [3 100] |
第2天 下午02
003 切片
使用
切片移除
D:\GoWork\src\code\day02\slice5.go
package main
import "fmt"
func main() {
// 移除切片操作
// 第一个元素或最后一个元素
nums := []int{1, 2, 3, 4, 5}
//start == 0 start省略
// 移除第一个元素
nums = nums[1:]
fmt.Println(nums)
//移除最后一个元素
nums = nums[:len(nums)-1]
fmt.Println(nums)
//移除中间的元素怎么办?
//[2 3 4] 移除3(index)
//切片操作 copy
// [index:] [3,4]
// [index+1:] [4]
// copy([index:],[index+1:]) [2,4,4]
copy(nums[1:], nums[2:])
nums = nums[:len(nums)-1]
fmt.Println(nums)
}
队列
package main
import "fmt"
func main() {
// 队列
// 先进先出
queue:=[]string{}
//push
//append
queue=append(queue,"a","b")
queue=append(queue,"c")
// pop
x:=queue[0]
queue=queue[1:]
fmt.Println("1:",x)
x=queue[0]
queue=queue[1:]
fmt.Println("2:",x)
x=queue[0]
queue=queue[1:]
fmt.Println("3:",x)
}
堆栈
package main
import "fmt"
func main() {
//堆栈
//先进后出
stack:=[]string{}
//push
//append
stack=append(stack,"a")
stack=append(stack,"b")
stack=append(stack,"c")
//pop
//后面移除
x:=stack[len(stack)-1]
stack=stack[:len(stack)-1]
fmt.Println("发射",x)
x=stack[len(stack)-1]
stack=stack[:len(stack)-1]
fmt.Println("发射",x)
x=stack[len(stack)-1]
stack=stack[:len(stack)-1]
fmt.Println("发射",x)
}
sort排序
package main
import (
"fmt"
"sort"
)
func main() {
nums:=[]int{3,2,1,6,90,7}
sort.Ints(nums)
fmt.Println(nums) //[1 2 3 6 7 90]
names:=[]string{"abc","xyz","mn","z","k"}
sort.Strings(names)
fmt.Println(names) //[abc k mn xyz z]
}
倒序
package main
import (
"fmt"
"sort"
)
func main() {
nums:=[]int{3,2,1,6,90,7}
//sort.Ints(nums)
sort.Sort(sort.Reverse(sort.IntSlice(nums)))
fmt.Println(nums) //[90 7 6 3 2 1]
}
二分查找
1 有序
//查找
//[0,100)
//50 大[0,50)
//24 小(24,50)
//x
//0,1,2,x,4,5......100
//[1,3,5,9,10] //有序 索引(0...4) => 中间索引2
//x是不是在切片中 x=5
//索引[0,4] 中间索引 2
//x=3 [0,4] 2 [0,2) 0 (0,2) 1 => 找到
//x=8 [0,4] 2 (2,4] 3 (2,3) 没找到
nums=[]int{1,3,5,9,10}
fmt.Println(nums[sort.SearchInts(nums,8)]==8) //false
fmt.Println(nums[sort.SearchInts(nums,5)]==5) //true
}
多维切片
package main
import "fmt"
func main() {
multi := [][]string{}
fmt.Printf("%T,%#v\n", multi, multi) //[][]string,[][]string{}
multi = append(multi, []string{"1", "2", "3"})
multi = append(multi, []string{"1", "2", "3", "5"})
fmt.Println(multi) //[[1 2 3] [1 2 3 5]]
fmt.Printf("%T,%#v\n", multi[0], multi[0]) //[]string,[]string{"1", "2", "3"}
fmt.Printf("%T,%#v\n", multi[0][1], multi[0][1]) //string,"2"
multi[0][1] = "xyz"
multi[1] = append(multi[1], "xxx")
fmt.Println(multi) //[[1 xyz 3] [1 2 3 5 xxx]]
}
nilslice和emptySlice
package main
import "fmt"
func main() {
var nilSlice []int
var emptySlice = []int{} //emptySlice := []int{}
fmt.Printf("%T %#v\n", nilSlice, nilSlice) //[]int []int(nil)
fmt.Printf("%T %#v\n", emptySlice, emptySlice) //[]int []int{}
nilSlice = append(nilSlice, 1)
emptySlice = append(emptySlice, 1)
fmt.Printf("%T %#v\n", nilSlice, nilSlice) //[]int []int{1}
fmt.Printf("%T %#v\n", emptySlice, emptySlice) //[]int []int{1}
}
004 map
映射 由键值对组成一种数据结构,通过key来对value进行操作
无序的数据结构
声明
D:\GoWork\src\code\day02\map.go
package main
import "fmt"
func main() { // 每个同学的成绩 // key => ID value => 成绩 var scores map[string]float64 fmt.Printf("%T %#v\n", scores, scores) //map[string]float64 map[string]float64(nil) } |
初始化(2种)+make方式
D:\GoWork\src\code\day02\map1.go
package main
import "fmt"
func main() { // 第一种 先声明 再赋值 var scores map[string]float64 scores = map[string]float64{} scores = map[string]float64{"22": 80, "23": 90, "37": 69} fmt.Printf("%T %#v\n", scores, scores)
// 第二种 声明并赋值 scores1 := map[string]float64{} fmt.Printf("%T %#v\n", scores1, scores1) //map[string]float64 map[string]float64{} scores1 = map[string]float64{"22": 80, "23": 90, "37": 69} fmt.Printf("%T %#v\n", scores1, scores1)
// make方式 等价于 == map[string]float64{} scores2 := make(map[string]float64) fmt.Printf("%T %#v\n", scores2, scores2) } |
zhu@DESKTOP-3LCQABF MINGW64 /d/GoWork/src/code/day02 $ go run map1.go map[string]float64 map[string]float64{"22":80, "23":90, "37":69} map[string]float64 map[string]float64{} map[string]float64 map[string]float64{"22":80, "23":90, "37":69} map[string]float64 map[string]float64{} |
操作
判断是否存在,用两个返回值
D:\GoWork\src\code\day02\map2.go
|
package main
import (
"fmt"
)
func main() {
//每个同学的成绩
// key => ID value =>成绩
var scores map[string]float64
fmt.Printf("%T,%#v\n",scores,scores) //map[string]float64,map[string]float64(nil)
// 初始化
// 字面量
scores = map[string]float64{} //空的map
fmt.Printf("%T,%#v\n",scores,scores)
scores = map[string]float64{"22":80,"23":90,"37":70}
fmt.Printf("%T,%#v\n",scores,scores)
//make
scores=make(map[string]float64) // == map[string]float64{}
fmt.Printf("%T,%#v\n",scores,scores)
// 操作
scores = map[string]float64{"22":80,"23":90,"37":70,"xx":0}
fmt.Println(len(scores)) //4
访问(查找)
// key => value
//查找
fmt.Println(scores["22"]) //80
fmt.Println(scores["xx"]) //0
fmt.Println(scores["yy"]) //0
// 判断key是否存在
v,ok:=scores["yy"]
fmt.Println(v,ok) //0 true
v,ok=scores["xx"]
fmt.Println(v,ok) //0 true
改&增
//改
scores["xx"]=100
fmt.Println(scores["xx"])
// 增
scores["yy"]=99
fmt.Println(scores)
scores["aa"]=99
fmt.Println(scores)
获取长度len
遍历
for v:=range scores{
fmt.Println(v,scores[v])
}
for k,v:=range scores{
fmt.Println(k,v)
}
}
删
//删
delete(scores,"yy")
fmt.Println(scores)
delete(scores,"bb")
fmt.Println(scores)
}
nilmap
package main
import "fmt"
func main() {
var nilMap map[string]string
fmt.Println(len(nilMap))
fmt.Println(nilMap["kk"])
//nilMap["kk"]="xx" //panic: assignment to entry in nil map
fmt.Printf("%#v\n",nilMap) //map[string]string(nil)
}
第2天 下午03
005 练习题 统计 我有一个梦想
我有一个梦想,每个英文(大小写区分)字母出现次数
package main
import "fmt"
/*
选班长:
小红,小李,小新,小李,小新,小李,小李
小红:1
小李:4
小新: 2
*/
//统计 我有一个梦想,每个英文(大小写区分)字母出现次数
func main() {
//字符串
article:=`I am happy to join with you today in what will go down in history as the greatest demonstration for freedom in the history of our nation.
Five score years ago, a great American, in whose symbolic shadow we stand today, signed the Emancipation Proclamation. This momentous decree came as a great beacon light of hope to millions of Negro slaves who had been seared in the flames of withering injustice. It came as a joyous daybreak to end the long night of bad captivity.
But one hundred years later, the Negro still is not free. One hundred years later, the life of the Negro is still sadly crippled by the manacles of segregation and the chains of discrimination. One hundred years later, the Negro lives on a lonely island of poverty in the midst of a vast ocean of material prosperity. One hundred years later, the Negro is still languished in the corners of American society and finds himself an exile in his own land. And so we've come here today to dramatize a shameful condition.
In a sense we've come to our nation's capital to cash a check. When the architects of our republic wrote the magnificent words of the Constitution and the Declaration of Independence, they were signing a promissory note to which every American was to fall heir. This note was a promise that all men, yes, black men as well as white men, would be guaranteed the "unalienable Rights" of "Life, Liberty and the pursuit of Happiness." It is obvious today that America has defaulted on this promissory note, insofar as her citizens of color are concerned. Instead of honoring this sacred obligation, America has given the Negro people a bad check, a check which has come back marked "insufficient funds."
But we refuse to believe that the bank of justice is bankrupt. We refuse to believe that there are insufficient funds in the great vaults of opportunity of this nation. And so, we've come to cash this check, a check that will give us upon demand the riches of freedom and the security of justice.
We have also come to this hallowed spot to remind America of the fierce urgency of Now. This is no time to engage in the luxury of cooling off or to take the tranquilizing drug of gradualism. Now is the time to make real the promises of democracy. Now is the time to rise from the dark and desolate valley of segregation to the sunlit path of racial justice. Now is the time to lift our nation from the quicksands of racial injustice to the solid rock of brotherhood. Now is the time to make justice a reality for all of God's children.
It would be fatal for the nation to overlook the urgency of the moment. This sweltering summer of the Negro's legitimate discontent will not pass until there is an invigorating autumn of freedom and equality. Nineteen sixty-three is not an end, but a beginning. And those who hope that the Negro needed to blow off steam and will now be content will have a rude awakening if the nation returns to business as usual. And there will be neither rest nor tranquility in America until the Negro is granted his citizenship rights. The whirlwinds of revolt will continue to shake the foundations of our nation until the bright day of justice emerges.
But there is something that I must say to my people, who stand on the warm threshold which leads into the palace of justice: In the process of gaining our rightful place, we must not be guilty of wrongful deeds. Let us not seek to satisfy our thirst for freedom by drinking from the cup of bitterness and hatred. We must forever conduct our struggle on the high plane of dignity and discipline. We must not allow our creative protest to degenerate into physical violence. Again and again, we must rise to the majestic heights of meeting physical force with soul force.
The marvelous new militancy which has engulfed the Negro community must not lead us to a distrust of all white people, for many of our white brothers, as evidenced by their presence here today, have come to realize that their destiny is tied up with our destiny. And they have come to realize that their freedom is inextricably bound to our freedom.
We cannot walk alone.
And as we walk, we must make the pledge that we shall always march ahead.
We cannot turn back.
There are those who are asking the devotees of civil rights, "When will you be satisfied?" We can never be satisfied as long as the Negro is the victim of the unspeakable horrors of police brutality. We can never be satisfied as long as our bodies, heavy with the fatigue of travel, cannot gain lodging in the motels of the highways and the hotels of the cities. We cannot be satisfied as long as the Negro's basic mobility is from a smaller ghetto to a larger one. We can never be satisfied as long as our children are stripped of their selfhood and robbed of their dignity by signs stating "for whites only." We cannot be satisfied as long as a Negro in Mississippi cannot vote and a Negro in New York believes he has nothing for which to vote. No, no, we are not satisfied, and we will not be satisfied until "justice rolls down like waters, and righteousness like a mighty stream."
I am not unmindful that some of you have come here out of great trials and tribulations. Some of you have come fresh from narrow jail cells. And some of you have come from areas where your quest -- quest for freedom left you battered by the storms of persecution and staggered by the winds of police brutality. You have been the veterans of creative suffering. Continue to work with the faith that unearned suffering is redemptive. Go back to Mississippi, go back to Alabama, go back to South Carolina, go back to Georgia, go back to Louisiana, go back to the slums and ghettos of our northern cities, knowing that somehow this situation can and will be changed.
Let us not wallow in the valley of despair, I say to you today, my friends.
And so even though we face the difficulties of today and tomorrow, I still have a dream. It is a dream deeply rooted in the American dream.
I have a dream that one day this nation will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident, that all man are created equal."
I have a dream that one day on the red hills of Georgia, the sons of former slaves and the sons of former slave owners will be able to sit down together at the table of brotherhood.
I have a dream that one day even the state of Mississippi, a state sweltering with the heat of injustice, sweltering with the heat of oppression, will be transformed into an oasis of freedom and justice.
I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.
I have a dream today!
I have a dream that one day, down in Alabama, with its vicious racists, with its governor having his lips dripping with the words of "interposition" and "nullification" -- one day right there in Alabama little black boys and black girls will be able to join hands with little white boys and white girls as sisters and brothers.
I have a dream today!
I have a dream that one day every valley shall be exalted, and every hill and mountain shall be made low, the rough places will be made plain, and the crooked places will be made straight; "and the glory of the Lord shall be revealed and all flesh shall see it together."
This is our hope, and this is the faith that I go back to the South with.
With this faith, we will be able to hew out of the mountain of despair a stone of hope. With this faith, we will be able to transform the jangling discords of our nation into a beautiful symphony of brotherhood. With this faith, we will be able to work together, to pray together, to struggle together, to go to jail together, to stand up for freedom together, knowing that we will be free one day.
And this will be the day -- this will be the day when all of God's children will be able to sing with new meaning:
My country 'tis of thee, sweet land of liberty, of thee I sing.
Land where my fathers died, land of the Pilgrim's pride,
From every mountainside, let freedom ring!
And if America is to be a great nation, this must become true.
And so let freedom ring from the prodigious hilltops of New Hampshire.
Let freedom ring from the mighty mountains of New York.
Let freedom ring from the heightening Alleghenies of
Pennsylvania.
Let freedom ring from the snow-capped Rockies of Colorado.
Let freedom ring from the curvaceous slopes of California.
But not only that:
Let freedom ring from Stone Mountain of Georgia.
Let freedom ring from Lookout Mountain of Tennessee.
Let freedom ring from every hill and molehill of Mississippi.
From every mountainside, let freedom ring.
And when this happens, when we allow freedom ring, when we let it ring from every village and every hamlet, from every state and every city, we will be able to speed up that day when all of God's children, black men and white men, Jews and Gentiles, Protestants and Catholics, will be able to join hands and sing in the words of the old Negro spiritual:
Free at last! Free at last!
Thank God Almighty, we are free at last!`
//遍历英文字母,for range
stat:=map[rune]int{}
for _,ch:=range article{
if ch>='a' && ch<='z' || ch>='A'&& ch<='Z' {
stat[ch]++
}
}
//fmt.Println(stat)
for ch,cnt:=range stat {
fmt.Printf("%c,%d\n",ch,cnt)
}
/* // 过滤掉非英文字符(byte/rune) 整数
// xxx a - z xxxx A-Z
// >='a' && <='z' || >='A' <='Z'
ch:='A'
//cnt,ok:=stat[ch]
//if ok {
// stat[ch]=cnt+1
//}else{
// //stat[ch]=1
// stat[ch]=cnt+1 // 不存在为0 0+1还是1
//}
//stat[ch]=stat[ch]+1 // a=a+b a+=b
//stat[ch]+=1
stat[ch]++*/
}
006 字符串
字符串类型
Go语言内置了字符串类型,使用string表示
字面量:
⚫ 可解析字符串:通过双引号(")来创建,不能包含多行,支持特殊字符转义序列
⚫ 原生字符串:通过反引号(`)来创建,可包含多行,不支持特殊字符转义序列
特殊字符:
⚫ \\:反斜线
⚫ \':单引号
⚫ \":双引号
⚫ \a:响铃
⚫ \b:退格
⚫ \f:换页
⚫ \n:换行
⚫ \r:回车
⚫ \t:制表符
⚫ \v:垂直制表符
⚫ \ooo:3 个 8 位数字给定的八进制码点的 Unicode 字符(不能超过\377)
⚫ \uhhhh:4 个 16 位数字给定的十六进制码点的 Unicode 字符
⚫ \Uhhhhhhhh:8 个 32 位数字给定的十六进制码点的 Unicode 字符
⚫ \xhh:2 个 8 位数字给定的十六进制码点的 Unicode 字符
package main
import "fmt"
func main() {
ascii := "abc我爱中华人民共和国"
fmt.Println([]byte(ascii)) //[97 98 99 230 136 145 231 136 177 228 184 173 229 141 142 228 186 186 230 176 145 229 133 177 229 146 140 229 155 189]
fmt.Println([]rune(ascii)) //[97 98 99 25105 29233 20013 21326 20154 27665 20849 21644 22269]
fmt.Println(len(ascii)) //30
fmt.Println(len([]rune(ascii))) //12
}
字符串和字节切片转换
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
ascii := "abc我爱中华人民共和国"
fmt.Println([]byte(ascii)) //[97 98 99 230 136 145 231 136 177 228 184 173 229 141 142 228 186 186 230 176 145 229 133 177 229 146 140 229 155 189]
fmt.Println([]rune(ascii)) //[97 98 99 25105 29233 20013 21326 20154 27665 20849 21644 22269]
fmt.Println(len(ascii)) //30
fmt.Println(len([]rune(ascii))) //12
fmt.Println(utf8.RuneCountInString(ascii))
fmt.Println(string([]byte(ascii)))
fmt.Println(string([]rune(ascii)))
}
strconv
// int float bool
fmt.Println(strconv.Itoa('a'))
ch,err:=strconv.Atoi("97")
fmt.Println(ch,err)
fmt.Println(strconv.FormatFloat(3.1415926,'f',10,64)) // 格式f 保留10位精度 float64
pi,err:=strconv.ParseFloat("3.1415626",64)
fmt.Println(pi,err)
fmt.Println(strconv.FormatBool(true))
fmt.Println(strconv.ParseBool("true"))
b,err:=strconv.ParseInt("65535",10,8) // 10进制 8位
fmt.Println(b,err) //127 strconv.ParseInt: parsing "65535": value out of range
fmt.Println(strconv.FormatInt(15,16)) // 转16进制
fmt.Println(strconv.FormatInt(15,2)) // 转2进制
}
strings
比较Compare
import (
"fmt"
"strings"
)
func main() {
// 比较大小
fmt.Println(strings.Compare("a","b"))
fmt.Println(strings.Compare("a","a"))
fmt.Println(strings.Compare("b","a"))
}
包含Contains & ContainsAny
包含1个ContainsAny
package main
import (
"fmt"
"strings"
)
func main() {
//包含
fmt.Println(strings.Contains("我是kk", "kk")) //true
fmt.Println(strings.Contains("我是kk", "kk1")) //false
//只要包含一个就true
fmt.Println(strings.ContainsAny("我是kk", "kk")) //true
fmt.Println(strings.ContainsAny("我是kk", "kk1")) //true
fmt.Println(strings.ContainsRune("我是kk", '我')) //true
fmt.Println(strings.ContainsRune("我是kk", 'a')) //false
}
计算次数Count
// 计算次数
fmt.Println(strings.Count("我是kk","kk")) //1
fmt.Println(strings.Count("我是kk","k")) //2
fmt.Println(strings.Count("我是kk","kak")) //0
不区分大小写的比较 EqualFold
fmt.Println(strings.EqualFold("abc","ABC")) //true
fmt.Println(strings.EqualFold("abc","abc")) //true
fmt.Println(strings.EqualFold("abc","XYZ")) //false
分割 Fields 空白符分割
//空白符
//空格 tab 回车 换行 换页 ...
fmt.Printf("%#v\n",strings.Fields("a b\tc\nd\re\ff")) //[]string{"a", "b", "c", "d", "e", "f"}
开头HasPrefix 结尾HasSuffix
//开头HasPrefix 结尾HasSuffix
fmt.Println(strings.HasPrefix("abc","ab")) //true
fmt.Println(strings.HasPrefix("abc","bc")) //false
//结尾HasSuffix
fmt.Println(strings.HasSuffix("abc","ab")) //false
fmt.Println(strings.HasSuffix("abc","bc")) //true
字符串出现的位置 index & LastIndex
//字符串出现的位置
fmt.Println(strings.Index("abcdefdef","def")) //3
fmt.Println(strings.Index("abcdefdef","xxx")) //-1
fmt.Println(strings.LastIndex("abcdefdef","def")) //6
fmt.Println(strings.LastIndex("abcdefdef","xxx")) //-1
连接join 分割 Split
分割两个部分
// 连接 分割
fmt.Println(strings.Join([]string{"ab","cd","ef"},"-")) //ab-cd-ef
fmt.Println(strings.Split("ab-cd-ef","-")) //[ab cd ef]
fmt.Println(strings.SplitN("ab-cd-ef","-",2)) //[ab cd-ef]
重复Repeat
// 重复
fmt.Println(strings.Repeat("*",5)) //*****
}
替换Replace
// 替换replace
fmt.Println(strings.Replace("xyzxyzxxxxyz", "yz", "mn", -1)) //xmnxmnxxxxmn
fmt.Println(strings.Replace("xyzxyzxxxxyz", "yz", "mn", 1)) //xmnxyzxxxxyz
fmt.Println(strings.ReplaceAll("xyzxyzxxxxyz", "yz", "mn")) //xmnxmnxxxxmn
}
首字母大写 Title
// 首字母大写
fmt.Println(strings.Title("my name is kk")) //My Name Is Kk
转大写ToUpper或小写 Tolower
fmt.Println(strings.ToUpper("abcABC")) //ABCABC
fmt.Println(strings.ToLower("abcABC")) //abcabc
行数行尾去除Trim
//Trim
fmt.Println(strings.Trim("abcdefabc","bc")) //abcdefa
fmt.Println(strings.Trim("abcdefabc","abc")) //def
fmt.Println(strings.TrimLeft("cabcdefabc","abc")) //defabc //左边字符串出现在子字符串中则替换
fmt.Println(strings.TrimRight("cabcdefabca","abc")) //cabcdef
fmt.Println(strings.TrimPrefix("abccabcdefabc","abc")) //cabcdefabc //字符串当成一个整体替换
fmt.Println(strings.TrimSuffix("abccabcdefabc","abc")) //abccabcdef
Bytes
比较bytes.Compare
fmt.Println(bytes.Compare([]byte("abc"),[]byte("xyz"))) //-1
007 排序算法
冒泡排序
heighs=[]int{168,180,166,170,169}
第一次 heighs[0]、 heighs[1] 不交换 []int{168,180,166,170,169}
第二次 heights[1]、 heighs[2] 交换 []int{168,166,180,170,169}
第三次 heights[1]、 heighs[2] 交换 []int{168,166,170,180,169}
第四次 heights[1]、 heighs[2] 交换 []int{168,166,170,169,180}
先将最高的排到队尾
算法:总是从第一个开始比较,如果前面的人高,交换两个人位置
交换方法
package main
import "fmt"
func main() {
// heigh :=[]int{168,180,166,176,169}
//a:=1
//b:=2
a,b:=1,2
a,b=b,a
fmt.Println(a,b) // 2 1
//交换
tmp:=a
a=b
b=tmp
fmt.Println(a,b) // 1 2
}
比较n-1次
第一轮
package main
import "fmt"
func main() {
heigh :=[]int{168,180,166,176,169}
for i:=0;i<len(heigh)-1;i++{
if heigh[i]>heigh[i+1]{
heigh[i],heigh[i+1]=heigh[i+1],heigh[i]
}
fmt.Println(i,heigh)
}
fmt.Println(heigh)
}
打印结果
0 [168 180 166 176 169]
1 [168 166 180 176 169]
2 [168 166 176 180 169]
3 [168 166 176 169 180]
[168 166 176 169 180]
做n次
package main
import "fmt"
func main() {
heighs := []int{168,180,166,170,169}
for j:=0;j<len(heighs)-1;j++ {
//for i := 0; i < len(heighs)-1-j; i++ { 每轮少比一次行不行?
for i := 0; i < len(heighs)-1; i++ {
if heighs[i] > heighs[i+1] {
heighs[i], heighs[i+1] = heighs[i+1], heighs[i]
}
fmt.Println(i, heighs)
}
fmt.Println(heighs)
}
}
008 作业
1 冒泡排序 2 切片,获取切片中第二大最大元素(相同大小的元素) 1 2 4 5 5 并排第一 4 不并排 5 思路: 元素去重: result:=[]type{} / make([]type,0,len(src)) src //遍历 elements = map[key]type{} //不在,放入result并且放入elements 找最大的第二大元素 每拿一个和最大的比, 如果比最大的值大,就把最大的放到第二大的 如果没有最大的大,和第二大的比,如果比第二大的大,放到第二大,如果没有,不改变 max = result[0] maxsec = result[0]
先排序,再比较 len-2
3 插入排序
4 二分查找元素
|
解答02
D:\GoWork\src\code\day02\homework\1.go
package main
import ( "fmt" "sort" )
func main() { // 切片 nums := []int{0, 1, 9, 2, 5, 6, 4, 4, 7, 8, 8, 3, 9}
//去重 elements := make(map[int]bool) for _, item := range nums { _, ok := elements[item] if !ok { elements[item] = true } } var result = []int{} // fmt.Println(elements) for k, _ := range elements { result = append(result, k) } fmt.Println("去重后切片元素:",result)
//排序,并列第一 sort.Ints(result) fmt.Println("并列第一,第二大元素为:",result[len(result)-2])
//排序,不并列第一 sort.Ints(nums) fmt.Println("不并列第一,第二大元素为:",nums[len(nums)-2]) } |
D:\GoWork\src\code\day02\homework>go run 1.go 去重后切片元素: [9 2 4 7 3 0 1 8 5 6] 并列第一,第二大元素为: 8 不并列第一,第二大元素为: 9 |
第2天 补充(常见排序)
课程内容
选择排序
插入排序
快速排序(二分查找)
001 选择排序
介绍
选择排序也属于内部排序法,按指定规则选出某一元素,经过和其他元素重整,再依原则交换位置后达到排序的目的
选择排序思路分析图
初始状态 【 8 3 2 1 7 4 6 5 】
第1次 【 1 3 2 8 7 4 6 5 】
第二次 【 1 2 3 5 7 4 6 5 】
第三次 【 1 2 3 8 7 4 6 5 】
第四次 【 1 2 3 4 7 8 6 5 】
第五次 【 1 2 3 4 5 8 6 7 】
第六次 【 1 2 3 4 5 6 8 7 】
第七次 【 1 2 3 4 5 6 7 8 】
select sort
从大到小排,先把最大的排在第一位
代码实现
package main
import "fmt"
func SelectSort(arr *[8]int) {
//标准的访问方式
// (*arr)[1] = 100 等价于 arr[1] = 900
//1 先完成将第一个最小值和arr[0] =>先易后难
//1 假设array[0]最小
min := arr[0]
minIndex := 0
//2 遍历后面 1 -- [len(n)-1]比较
for i := 0 + 1; i < len(arr); i++ {
if arr[i] < min {
min = arr[i]
minIndex = i
}
}
//交换
if minIndex != 0 {
arr[0], arr[minIndex] = arr[minIndex], arr[0]
}
fmt.Println("第1次", arr)
//第二次
min = arr[1]
minIndex = 1
//2 遍历后面 1 -- [len(n)-1]比较
for i := 1 + 1; i < len(arr); i++ {
if arr[i] < min {
min = arr[i]
minIndex = i
}
}
//交换
if minIndex != 1 {
arr[1], arr[minIndex] = arr[minIndex], arr[1]
}
fmt.Println("第2次", arr)
//第n次 8位数 比较7次 n=7
for j := 0; j < len(*arr)-1; j++ {
min = arr[j]
minIndex = j
//2 遍历后面 1 -- [len(n)-1]比较
for i := j + 1; i < len(arr); i++ {
if arr[i] < min {
min = arr[i]
minIndex = i
}
}
//交换
if minIndex != j {
arr[j], arr[minIndex] = arr[minIndex], arr[j]
}
fmt.Printf("第%d次 %v\n", j+1, arr)
}
}
func main() {
//定义一个数组,从小到大
arr := [8]int{8, 3, 2, 1, 7, 4, 6, 5}
SelectSort(&arr)
fmt.Println(arr)
}
002 插入排序
介绍
插入排序属于内部排序法,把n个待排序元素看成一个有序表和一个无序表
开始有序表中1个元素,无序表中n-1个元素。
从无序表取元素,插入有序表中
思路图
原始数组 【23】 0 12 56 34
第一次找到插入位置 【23, 0】 12 56 34
第二次找到插入位置 【23, 0, 0】 56 34
【23,12, 0】 56 34
第三次找到插入位置 【23,12, 0,0】 34
【23,12,12,0】 34
【23,23,12,0】 34
【56,23,12,0】 34
第四次找到插入位置 【56,23,12, 0,0】
【56,23,12,12,0】
【56,23,23,12,0】
【56,34,23,12,0】
代码实现
package main
import (
"fmt"
)
func InsertSort(arr *[5]int) {
//完成第一次,给第二元素找到合适的位置并插入
insertVal := arr[1]
insertIndex := 1 - 1 //下标
//从大到小
for insertIndex >= 0 && arr[insertIndex] < insertVal {
arr[insertIndex+1] = arr[insertIndex] //数据后移
insertIndex--
}
//插入
if insertIndex+1 != 1 {
arr[insertIndex+1] = insertVal
}
fmt.Println("第一次插入后", *arr)
//完成第2次,给第3个元素找到合适的位置并插入
insertVal = arr[2]
insertIndex = 2 - 1 //下标
//从大到小
for insertIndex >= 0 && arr[insertIndex] < insertVal {
arr[insertIndex+1] = arr[insertIndex] //数据后移
insertIndex--
}
//插入
if insertIndex+1 != 2 {
arr[insertIndex+1] = insertVal
}
fmt.Println("第2次插入后", *arr)
}
func main() {
arr := [5]int{23, 0, 12, 56, 34}
fmt.Println("原始数组=", arr)
InsertSort(&arr)
fmt.Println("main 函数")
fmt.Println(arr)
}
打印结果
D:\GoWork\src\go_course\sort>go run main.go
原始数组= [23 0 12 56 34]
第一次插入后 [23 0 12 56 34]
第2次插入后 [23 12 0 56 34]
main 函数
[23 12 0 56 34]
最终代码
package main
import (
"fmt"
)
func InsertSort(arr *[5]int) {
//完成第一次,给第二元素找到合适的位置并插入
for i:=1;i<len(arr);i++{
insertVal := arr[i]
insertIndex := i - 1 //下标
//从大到小
for insertIndex >= 0 && arr[insertIndex] < insertVal {
arr[insertIndex+1] = arr[insertIndex] //数据后移
insertIndex--
}
//插入
if insertIndex+1 != i {
arr[insertIndex+1] = insertVal
}
fmt.Printf("第%d次插入后 %v\n",i, *arr)
}
}
func main() {
arr := [5]int{23, 0, 12, 56, 34}
fmt.Println("原始数组=", arr)
InsertSort(&arr)
fmt.Println("main 函数")
fmt.Println(arr)
}
打印结果
D:\GoWork\src\go_course\sort>go run main.go
原始数组= [23 0 12 56 34]
第1次插入后 [23 0 12 56 34]
第2次插入后 [23 12 0 56 34]
第3次插入后 [56 23 12 0 34]
第4次插入后 [56 34 23 12 0]
main 函数
[56 34 23 12 0]
003 快速排序
介绍
快速排序是对冒泡排序的一种改进。基本思路:通过一趟排序将要排序的数据分割成独立的两部分,一部分所有数据比另一部分所有数据都小,然后按此方法对这两部分数据分别进行快速排序,整个过程可以递归进行,以此达到整个数据变成有序序列
思路图
代码实现
package main
import "fmt"
//快速排序
func QuickSort(left int, right int, array *[9]int) {
l := left
r := right
// pivot是中轴,支点
pivot := array[(left+right)/2]
temp := 0
//for循环的目标是将比pivot小的数放到左边
// 比pivot大的数放到 右边
for l < r {
//从 pivot的左边找到大于等于pivot的值
for array[l] < pivot {
l++
}
//从 pivot的右边找到大于等于pivot的值
for array[r] > pivot {
r--
}
// l>=r表名本次分解任务完成,break
if l >= r {
break
}
//交换
temp = array[l]
array[l] = array[r]
array[r] = temp
//优化(array[l]和arrar[r]交换,所以array[l]相当于array[r]的位置,位置再移)
if array[l] == pivot {
r--
}
if array[r] == pivot {
l++
}
}
//如果l==r,再移动下
if l == r {
l++
r--
}
//向左递归
if left < r {
QuickSort(left, r, array)
}
//向右递归
if right > l {
QuickSort(l, right, array)
}
}
func main() {
// arr := [6]int{-9, 78, 0, 23, -567, 70}
arr := [9]int{-9, 78, 0, 23, -567, 70, 123, 90, -23}
//调用快速排序
QuickSort(0, len(arr)-1, &arr)
fmt.Println(arr)
}
go中使用map的键排序
package main import ( "fmt" "sort" ) func main() { //待排序队列 var stuScore = map[int]string{1:"ee",5:"cc",4:"ff",9:"qq",3:"aa",2:"bb"} fmt.Println(stuScore) //map[1:ee 2:bb 3:aa 4:ff 5:cc 9:qq] nums:=make([]int,0) for k:=range stuScore{ nums=append(nums,k) } sort.Sort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums) //[9 5 4 3 2 1] for _,num:=range nums { fmt.Println(num,stuScore[num]) }
go中使用map的值排序
package main import ( "fmt" "sort" ) func main() { //待排序队列 var stuScore = map[string]int{"ee":20,"cc":90,"ff":70,"qq":40,"aa":79,"bb":30} //创建切片,遍历map的值 var nums = []int{} for _,v:=range stuScore { nums=append(nums,v) } //对切片按值排序 //sort.Ints(nums) sort.Sort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums) for _,num:=range nums { //遍历map的key和值,与切片中的元素做比对 for k,v:=range stuScore { if v==num { fmt.Println(k,v) } } } }