// 数组是可以存放多个同一类型数据。数组也是一种数据类型
// 在Go中,数组是值类型
package main
import (
"fmt"
"time"
)
func main() {
// 定义一个数组,当我们定义完一个数组后,数组会有一个默认值0
var hens [6]float64
// 给数组的每个元素赋值,元素的下标是从0开始的
hens[0] = 3.0
hens[1] = 5.0
hens[2] = 1.0
hens[3] = 5.0
hens[4] = 2.0
hens[5] = 50.0
// 遍历数组求出总体重
var totalWeight float64 = 0.0
for i := 0; i < len(hens); i++{
totalWeight += hens[i]
}
// 求出平均体重
averageWeight := fmt.Sprintf("%.2f", totalWeight / float64(len(hens)))
fmt.Printf("totalWeight=%v averageWeight=%v\n", totalWeight, averageWeight)
// 使用数组来解决问题,程序的可维护性增加了,更加灵活,易扩展
// 代码更加的而清晰
// (1)数组的四种初始化方式:
var numsArray01 [3]int = [3]int {1, 2, 3}
var numsArray02 = [3]int {4, 5, 6}
var numsArray03 = [...]int {7, 8, 9} // 这里的...是固定写法,让系统自动推导有多少值
// 还可以指定元素值对应的下标来赋值
var numsArray04 = [3]string{1:"tmo", 0:"jack", 2:"jerry"}
// 类型推导
numsArray05 := [...]int{1: 800, 0: 900, 2: 1000}
// 打印输出
start := time.Now().UnixNano()
fmt.Println("numsArray01=", numsArray01)
fmt.Println("numsArray02=", numsArray02)
fmt.Println("numsArray03=", numsArray03)
fmt.Println("numsArray04=", numsArray04)
fmt.Println("numsArray05=", numsArray05)
end := time.Now().UnixNano()
fmt.Println("输出所需时间:\n", end - start)
start1 := time.Now().UnixNano()
fmt.Println("numsArray01=", numsArray01, "numsArray02=", numsArray02, "numsArray03=", numsArray03, "numsArray04=", numsArray04, "numsArray05=", numsArray05)
end1 := time.Now().UnixNano()
fmt.Println("输出所需时间:", end1 - start1)
/*
numsArray01= [1 2 3]
numsArray02= [4 5 6]
numsArray03= [7 8 9]
numsArray04= [jack tmo jerry]
numsArray05= [900 800 1000]
*/
}
package main
import (
"fmt"
)
/*
数组的遍历 for-range
Go语言中独有的结构,可以遍历访问数组的元素
语法:
for index, value := range array01 {
...
}
说明:
1)第一个返回值indx是数组的下标
2)第二个value是在该下标位置的值
3)他们都是仅在for循环内部可见的局部变量
4)遍历数组元素的时候,如果不想使用下标index,可以直接把下标index标为下划线 _
5)index和value的名称是不固定的,即程序员可以自行指定,一般命名为index,values
*/
func main() {
// intArry := [...]int{0: 110, 1: 1201, 2: 232, 3: 12133, 4: 1245, 5: 3452, 6: 2345, 7: 1245, 8: 1215, 9: 3421}
intArry := [...]int{110, 1201, 232, 12133, 1245, 3452, 2345, 1245, 1215, 3421}
for i, v := range intArry {
fmt.Printf("i=%v v=%v\n", i, v)
}
for _, v := range intArry {
fmt.Println(v)
}
}
package main
import (
"fmt"
)
func main() {
var arr [4][6]int
arr[1][2] = 1
arr[2][1] = 2
arr[2][3] = 3
for i := 0; i < 4; i++ {
for j := 0; j < 6; j++ {
fmt.Print(arr[i][j], " ")
}
fmt.Println()
}
var arr2 [2][3]int
arr2[0][1] = 10
fmt.Println(arr2)
fmt.Printf("arr[0]的地址 =%p\n", &arr[0])
fmt.Printf("arr[1]的地址 =%p\n", &arr[1])
fmt.Printf("arr[0][0]的地址 =%p\n", &arr[0][0])
fmt.Printf("arr[1][0]的地址 =%p\n", &arr[1][0])
// 输出内容:
// arr[0]的地址 =0xc00008a000
// arr[1]的地址 =0xc00008a030
// arr[0][0]的地址 =0xc00008a000
// arr[1][0]的地址 =0xc00008a030
// 二维数组的初始化声明
var arr3 [2][3]int = [2][3]int{{1, 2, 3}, {4, 5, 6}}
// 或者如下声明:var arr3 [2][3]int = [...][3]int{{1, 2, 3}, {4, 5, 6}}
// 或者如下声明:var arr3 = [...][3]int{{1, 2, 3}, {4, 5, 6}}
// 或者如下声明:arr3 := [...][3]int{{1, 2, 3}, {4, 5, 6}}
fmt.Println("arr3=", arr3)
}
package main
import (
"fmt"
)
// 定义一个二维数组,统计三个班,每个班5个同学的成绩
// 并统计每个班的平均分及所有班级的平均分
func main() {
var scores [3][5]float64
var totalSum float64
for i := 0; i < len(scores); i++ {
sum := 0.0
for j := 0; j < len(scores[i]); j++ {
fmt.Printf("请输入第%d个班,第%v个人的成绩 \n", i + 1, j + 1)
fmt.Scanln(&scores[i][j])
sum += scores[i][j]
}
totalSum += sum
fmt.Printf("第%d个班的平均分%v \n", i + 1, sum / float64(len(scores[i])))
}
fmt.Printf("所有班级的总分为%v, 平均分为%v", totalSum, (totalSum / 15))
}
package main
import (
"fmt"
)
// 二维数组的遍历。
// (1)双从for循环遍历
// (2)for-raneg 遍历
func main() {
arr := [...][5]int{{1, 2, 3, 4, 5}, {2, 4, 6, 8, 9}}
// (1)双从for循环遍历
fmt.Printf("arr的长度=%v\n", len(arr))
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
fmt.Printf("%v\t", arr[i][j])
}
fmt.Println()
}
// (2)for-raneg 遍历
for i, v := range arr {
for j, v1 := range v {
fmt.Printf("arr[%v][%v]=%v \t", i, j, v1)
}
fmt.Println()
}
}
在Golang中,常用的查找有两种
package main
import (
"fmt"
)
func main() {
// 定义一个数组,从控制台接收一个名字,依次比较,如果发现有,则提示在数组中哪个下标的位置
// 顺序查找1:
name := [4]string{"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"}
var heroName = ""
fmt.Println("请输入一个英雄的名字:")
fmt.Scanln(&heroName)
// for i := 0; i < len(name); i++ {
// if heroName == name[i] {
// fmt.Printf("英雄的名字是%v ,下标是%d", heroName, i)
// } else if i == (len(name) - 1) {
// fmt.Printf("没找到%v", heroName)
// }
// }
// 顺序查找2:
index := -1
for i := 0; i < len(name); i++ {
if heroName == name[i] {
index = i
break
}
}
if index != -1 {
fmt.Printf("英雄的名字是%v ,下标是%d", heroName, index)
} else {
fmt.Printf("没找到%v", heroName)
}
}
package main
import (
"fmt"
)
// 二分法,查找原理,如查找findVal
// 1)首先一个数组arr是一个有序数组,且是从小到大
// 2)先找到中间下标 middle = (leftIndex + rightIndex) / 2,然后让中间下标的值和findVal进行比较
// 3)如果arr[middle] > findVal ,就应该向 leftIndex -- (middle - 1) 这个范围去查找
// 4)如果arr[middle] < findVal ,就应该向 (middle + 1) -- rightIndex 这个范围去查找
// 5)如果arr[middle] == findVal ,就找到了
// 上边得逻辑会递归执行
// 4)如果leftIndex大于rightIndex相等,那么就意味着没有找到,可以return
func BinaryFind(arr *[6]int, leftIndex int, rightIndex int, findVal int) {
if leftIndex > rightIndex {
fmt.Println("找不到")
return
}
middle := (leftIndex + rightIndex) / 2
if (*arr)[middle] > findVal {
BinaryFind(arr, leftIndex, middle - 1, findVal)
} else if (*arr)[middle] < findVal {
BinaryFind(arr, middle + 1, rightIndex, findVal)
} else {
fmt.Printf("找到了,下标为%v", middle)
}
}
func main() {
arr := [6]int{1, 8, 10, 89, 1000, 1234}
BinaryFind(&arr, 0, len(arr) - 1, 11)
}
排序是指将一组数据,依照指定的顺序进行排列的过程
排序分类:
交换式排序法:
1)冒泡排序(Bubble sort)
2)快速排序(Quick Sort)
package main
import (
"fmt"
)
// 冒泡排序整个流程
func bubbleSort(arr *[5]int) {
// 交换前arr
fmt.Println("交换前arr=", *arr)
for j := len(*arr); j > 1; j-- {
for i := 0; i < len(*arr) - 1; i++ {
if (*arr)[i] > (*arr)[i + 1] {
// 传统交换方法:
// t = arr[i]
// arr[i] = arr[i + 1]
// arr[i + 1] = t
(*arr)[i], (*arr)[i + 1] = (*arr)[i + 1], (*arr)[i]
}
}
}
fmt.Println("交换后arr=", *arr)
}
func main() {
var arr = [...]int{24, 69, 80, 57, 13}
bubbleSort(&arr)
// 输出内容
// 交换前arr= [24 69 80 57 13]
// 交换后arr= [13 24 57 69 80]
}
package main
import (
"fmt"
)
func main() {
var intArray [3]int // int占八个字节
fmt.Println(intArray)
// 数组的第一个元素的地址就是数组的首地址
fmt.Printf("intArray的地址=%p intArray[0]的地址=%p intArray[1]的地址=%p intArray[2]的地址=%p\n",
&intArray, &intArray[0], &intArray[1], &intArray[2])
// intArray的地址=0xc000054120 intArray[0]的地址=0xc000054120
// intArray[1]的地址=0xc000054128 intArray[2]的地址=0xc000054130
// 如果想要快速定位一个数组的值,最快速的方法就是在地址+值类型占用字节,int64 8字节
// 数组的各个元素的地址间隔是依据数组的类型决定的,比如int64 -> 8 int32 -> 4
var score [5]float64
for i := 0; i < 5; i++ {
fmt.Printf("请输入第%d个学生的成绩:", i + 1)
fmt.Scanln(&score[i])
}
for i := 0; i < 5; i++ {
fmt.Printf("第 %d 个学生的成绩是:%v\n", i + 1, score[i])
}
}
package main
import (
"fmt"
)
func main() {
// (1)创建一个byte类型的26个元素的数组,分别放置'A'-'Z'。使用for循环访问所有元素并打印出来
// 字符数据运算 'A' + 1 -> 'B'
var arrByte [26]byte
for i := 0; i < len(arrByte); i++ {
arrByte[i] = 'A' + byte(i)
}
for i := 0; i < len(arrByte); i++ {
fmt.Printf("arrByte[%d]= %c\n", i, arrByte[i])
}
// (2)求出一个数组的最大值,并得到对应的下标
arrInt := [5]int{10, 33, 44, 12, 23}
maxVal := arrInt[0]
maxValIndex := 0
for i := 1; i < len(arrInt); i++ {
if maxVal < arrInt[i] {
maxVal = arrInt[i]
maxValIndex = i
}
}
fmt.Printf("最大值是%v index=%v\n", maxVal, maxValIndex)
// (3)求出一个数组的和和平均值,for-range
sum := 0
average := 0.0
for i, _ := range arrInt {
sum += arrInt[i]
}
average = float64(sum) / float64(len(arrInt)) // 这样可以保留小数点位
fmt.Printf("和是%v 平均值是%v\n", sum, average)
}
package main
import (
"fmt"
"math/rand"
"time"
)
// 随机生成五个数,并反转打印
func main() {
rand.Seed(time.Now().UnixNano())
// n := rand.Intn(100) // [0-100)
var arrInt [5]int
for i := 0; i < len(arrInt); i++ {
arrInt[i] = rand.Intn(100)
}
fmt.Println(arrInt)
var arrInt2 [5]int
for i := len(arrInt2); i > 0; i-- {
arrInt2[len(arrInt2) - i] = (arrInt[i - 1])
}
arrInt = arrInt2
fmt.Println(arrInt)
}
有几个练习题可以做一下
package main
import (
"fmt"
"math/rand"
"time"
)
// 随机生成10个整数(1-100)范围内的,保存到数组中,并倒序打印以及求平均值、最大值和下标、并查找里边是不是有55
func main() {
rand.Seed(time.Now().UnixNano())
var arr [10]int
for i := 0; i < 10; i++ {
arr[i] = (rand.Intn(100) + 1)
}
fmt.Println("交换前arr=", arr)
for i := len(arr); i > 0; i-- {
for j := 0; j < len(arr) - 1; j++ {
if arr[j] < arr[j + 1] {
arr[j], arr[j + 1] = arr[j + 1], arr[j]
}
}
}
fmt.Println("交换后arr=", arr)
sum := 0
for _, v := range arr {
if v == 55 {
fmt.Println("查到55在数组中")
}
sum += v
}
fmt.Printf("arr的平均值=%v\n", float64(sum) / float64(len(arr)))
}
package main
import (
"fmt"
)
// 有一个排序好的数组,要求插入一个元素,最后打印该数组,顺序依然是升序
func main() {
var arr [5]int = [5]int{2, 4, 6, 8, 10}
slice := arr[:]
slice = append(slice, 3)
for i := len(slice) - 1; i > 0; i-- {
if slice[i] < slice[i - 1] {
slice[i], slice[i - 1] = slice[i - 1], slice[i]
}
}
fmt.Println("slice=", slice)
}
package main
import (
"fmt"
)
// 定义一个三行四列的二维数组,逐个从键盘输入值,编写程序将四周的数据清0
func main() {
var arr [3][4]int
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
fmt.Printf("请输入arr[%d][%d]的数字:\n", i, j)
fmt.Scanln(&arr[i][j])
}
}
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
if i == 0 || i == 2 || i == 1 && j == 0 || j == 3{
arr[i][j] = 0
}
}
}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
}
package main
import (
"fmt"
)
// 定义一个四行四列的二维数组,逐个从键盘输入值,然后将第一行和第四行的数据进行交换,将第二行喝第三行的数据进行交换
func main() {
var arr [4][4]int
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
fmt.Printf("请输入arr[%d][%d]的数字:\n", i, j)
fmt.Scanln(&arr[i][j])
}
}
fmt.Println("替换前arr= ", arr)
for i := 0; i < len(arr); i++ {
for j := 0; j < len(arr[i]); j++ {
if i == 0 {
arr[i][j], arr[3][j] = arr[3][j], arr[i][j]
} else if i == 1 {
arr[i][j], arr[2][j] = arr[2][j], arr[i][j]
}
}
}
fmt.Println("替换后arr=")
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
}
package main
import (
"fmt"
)
// 保存1 3 5 7 9 五个奇数到数组,并倒序打印
func main() {
var arr [5]int = [5]int{1, 3, 5, 7, 9}
for i := len(arr); i > 0; i-- {
for j := 0; j < len(arr) - 1; j++ {
if arr[j] < arr [j + 1] {
arr[j], arr[j + 1] = arr[j + 1], arr[j]
}
}
}
fmt.Println("倒叙后arr=", arr)
}
package main
import (
"fmt"
)
// 有个arr [10]string 数组,查询 "AA"是否在数组中,并打印下标,若存在多个 "AA",则一并打印出所有下标
func main() {
arr := [10]string{"AA", "BB", "CC", "DD", "EE", "AA", "GG", "HH", "II", "JJ"}
for i, v := range arr {
if "AA" == v {
fmt.Printf("AA的下标是%d\n", i)
}
}
}
package main
import (
"fmt"
"math/rand"
"time"
)
// 生成10个随机数(1-100之间),使用冒泡排序,然后使用二分查找,查找是否有90这个数,并显示下标,如果没有则提示“找不到该数字”
func Search(arr *[10]int, leftIndex int, rightIndex int, findVal int) {
if leftIndex > rightIndex {
fmt.Printf("找不到%v", findVal)
return
}
middle := (leftIndex + rightIndex) / 2
if (*arr)[middle] > findVal {
Search(arr, leftIndex, middle - 1, findVal)
} else if (*arr)[middle] < findVal {
Search(arr, middle + 1, rightIndex, findVal)
} else {
fmt.Printf("找到了,下标为%v", middle)
}
}
func main() {
rand.Seed(time.Now().UnixNano())
// 声明变量并生成数据
var arr [10]int
for i := 0; i < 10; i++ {
arr[i] = (rand.Intn(100) + 1)
}
fmt.Println("排序前add=", arr)
// 冒泡排序
for i := len(arr); i > 0 ; i-- {
for j := 0; j < len(arr) - 1; j++ {
if arr[j] > arr[j + 1] {
arr[j], arr[j + 1] = arr[j + 1], arr[j]
}
}
}
fmt.Println("排序后arr=", arr)
// 二分法查找
Search(&arr, 0, len(arr) - 1, 90)
}
package main
import (
"fmt"
)
// 编写一个函数,可以接收一个数组,该数组有5个数,找出最大数和最小数对应的的数组的下标
func searchArr(arr [5]int) {
max := arr[0]
min := arr[0]
for i := 0; i < len(arr) - 1; i++ {
if max >= arr[i + 1] {
max = arr[i]
if min > arr[i + 1] {
min = arr[i + 1]
}
} else {
if min > arr[i + 1] {
min = arr[i + 1]
}
max = arr[i + 1]
}
}
for i, v := range arr {
if max == v {
fmt.Println("max index = ", i)
}
if min == v {
fmt.Println("min index = ", i)
}
}
}
func main() {
arr := [5]int{10, 55, 22, 35, 30}
searchArr(arr)
}
package main
import (
"fmt"
)
// 定义一个数组,并给出8个整数,求该数组中大于平均值的数的个数和小于平均值的数的个数
func main() {
var arr [8]int = [8]int{10, 23, 13, 6, 9, 11, 33, 32}
var minCount int = 0
var maxCount int = 0
var sum int = 0
var average int = 0
for _, v := range arr {
sum += v
}
average = sum / len(arr)
for _, v := range arr {
if v > average {
maxCount++
} else if v < average {
minCount++
}
}
fmt.Printf("arr数组的平均值为%v\n", average)
fmt.Printf("大于平均值的数有%v个\n", maxCount)
fmt.Printf("小于平均值的数有%v个\n", minCount)
}
package main
import (
"fmt"
)
func main() {
var scores [8]float64
var finScore float64 = 0.0
var sum float64 = 0.0
for i := 0; i < len(scores); i++ {
fmt.Printf("请第%d个评委输入选手成绩:", i + 1)
fmt.Scanln(&scores[i])
}
var maxScore float64 = scores[0]
var minScore float64 = scores[0]
var maxIndex int
var minIndex int
for index, v := range scores {
if v > maxScore {
maxScore = v
maxIndex = index
}
if v < minScore {
minScore = v
minIndex = index
}
}
for _, v := range scores {
sum += v
}
finScore = (sum - scores[maxIndex] - scores[minIndex]) / float64(len(scores) - 2)
fmt.Printf("第%d位打的分数是最高分,打分是%v\n", maxIndex + 1, maxScore)
fmt.Printf("第%d位打的分数是最低分,打分是%v\n", minIndex + 1, minScore)
fmt.Printf("该选手最后得分是:%v\n", finScore)
var best [8]float64
var t float64
for i := 0; i < len(best); i++ {
t = (scores[i] - finScore)
if t < 0 {
t = - (t)
best[i] = t
} else {
best[i] = t
}
}
fmt.Println(best)
var maxScore2 float64 = best[0]
var minScore2 float64 = best[0]
var maxIndex2 int
var minIndex2 int
for index, v := range best {
if v > maxScore2 {
maxScore2 = v
maxIndex2 = index
}
if v < minScore2 {
minScore2 = v
minIndex2 = index
}
}
fmt.Printf("第%d位是最佳评委,与最终分相差%.2f分\n", minIndex2 + 1, minScore2)
fmt.Printf("第%d位是最差评委,与最终分相差%.2f分\n", maxIndex2 + 1, maxScore2)
}
注意事项及细节:
package main
import (
"fmt"
)
// (1)Go的数组属于值类型,在默认情况下是值传递,因此会进行值拷贝。数组间不会相互影响
func test01(arr1 [3]int) {
arr1[0] = 88
}
// (2)如果想在其他函数中去修改原来的数组,可以使用引用传递(指针方式)
func test02(arr2 *[3]int) {
(*arr2)[0] = 88
}
func main() {
arr1 := [3]int{11, 22, 33}
test01(arr1)
fmt.Println("main arr1 =", arr1) // 输出内容:main arr = [11 22 33]
arr2 := [3]int{44, 55, 66}
test02(&arr2)
fmt.Println("main arr2 =", arr2) // 输出内容:main arr2 = [88 55 66]
// 这里通过指针就可以修改数组里边的数据
}