Go 语言数组(下)

简介: 数组是相同数据类型的一组数据的集合,数组一旦定义长度不能修改,数组可以通过下标(或者叫索引)来访问元素。  相对于去声明 number0, number1, ..., number99 的变量,使用数组形式 numbers[0], numbers[1] ..., numbers[99] 更加方便且易于扩展。数组元素可以通过索引(位置)来读取(或者修改),索引从0 开始,第一个元素索引为 0,第二个索引为1,以此类推。

2. 根据数组长度遍历数组


可以根据数组长度,通过for循环的方式来遍历数组,数组的长度可以使用len函数获得

使用len()函数获取数组的长度


package main
import "fmt"
func main() {
 var a1 = [3]int{1, 2, 3}
 fmt.Printf("len(a1): %v\n", len(a1))
 var a2 = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
 fmt.Printf("len(a2): %v\n", len(a2))
}
//输出结果如下
len(a1): 3
len(a2): 9


数组遍历,根据长度和下标


package main
import "fmt"
func main() {
 a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
 for i := 0; i < len(a); i++ {
  fmt.Printf("a[%d]:%v\n", i, a[i])
 }
}
//输出结果如下
a[0]:1
a[1]:2
a[2]:3
a[3]:4
a[4]:5
a[5]:6
a[6]:7
a[7]:8
a[8]:9


使用for range


package main
import "fmt"
func main() {
 var a = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
 for i, v := range a {    //i也可以使用空白标识符代替,不接受索引的值
  fmt.Printf("a[%v]:%v\n", i, v)
 }
}
//输出结果如下
a[0]:1
a[1]:2
a[2]:3
a[3]:4
a[4]:5
a[5]:6
a[6]:7
a[7]:8
a[8]:9

 

四、冒泡排序



1. 控制台输入十名学生的成绩,如果低于60自动修改为60,并最终展示成绩清单


package main
import "fmt"
func main() {
 var source [10]float32 //分数
 var s float32          //初始化成绩
 //遍历数组
 for i := 0; i < 10; i++ {
  fmt.Printf("请输入第%d学生的成绩:", i+1)
  fmt.Scan(&s)
  if s < 60 {
   //修改为60分
   source[i] = 60
  } else {
   //添加学生成绩
   source[i] = s
  }
 }
 fmt.Println("成绩录入成功!")
 fmt.Println("成绩清单如下")
 for j := 0; j < 10; j++ {
  fmt.Printf("第%d名学生的成绩", j+1)
  fmt.Println(source[j])
 }
}
//终端输入结果
PS D:\goproject\src\dev_code\day10\test\main> go run .\
请输入第1学生的成绩:50
请输入第2学生的成绩:55
请输入第3学生的成绩:80
请输入第4学生的成绩:70
请输入第5学生的成绩:90
请输入第6学生的成绩:50
请输入第7学生的成绩:30
请输入第8学生的成绩:44
请输入第9学生的成绩:55
请输入第10学生的成绩:66
成绩录入成功!
成绩清单如下
第1名学生的成绩60
第2名学生的成绩60
第3名学生的成绩80
第4名学生的成绩70
第5名学生的成绩90
第6名学生的成绩60
第7名学生的成绩60
第8名学生的成绩60
第9名学生的成绩60
第10名学生的成绩66


2. 随机输入5个数字,求出最大值


package main
import (
 "fmt"
)
func main() {
 var (
  tmp     int    //用来接收比较出来最大的那个数字
  num     int    //录入的数字
  numbers [5]int //5个数字
 )
 for i := 0; i < 5; i++ {
  fmt.Printf("请输入第%d个数字:", i+1)
  fmt.Scan(&num)
  //输入的数字添加到集合中
  numbers[i] = num
 }
 fmt.Println("录入成功!")
 tmp = numbers[0]
 for j := 0; j < 5; j++ {
  //比较最大的数,大的那个数用tmp来接收保存,循环的进行比较
  if numbers[j] > tmp {  //如果是求最小值,把>改为<即可
   tmp = numbers[j]
  }
 }
 fmt.Println("最大值:", tmp)
}
//终端输入结果如下
PS D:\goproject\src\dev_code\day10\test\main> go run .\
请输入第1个数字:888
请输入第2个数字:756
请输入第3个数字:358
请输入第4个数字:218
请输入第5个数字:8489
录入成功!
最大值: 8489

 

3. 冒泡排序


思路

  • 冒泡排序要对一个列表多次重复遍历。它要比较相邻的两项,并且交换顺序排错的项,每对列表进行一次遍历,就有一个最大项排在了正确的位置。
  • 列表的每一个数据项都会在其相应的位置 冒泡。如果列表有 n 项,第一次遍历就要比较 n-1 对数据。
  • 一旦列表中最大的数是所比较的数据对中的一个,它就会沿着列表一直后移,直到这次遍历结束

2387773-20220328125637232-404779617.png


package main
import "fmt"
var arr = [...]int{34, 61, 22, 75, 42}
func main() {
 fmt.Println("初始值为:", arr)
 //外循环控制比较的轮数
 for j := 0; j < len(arr)-1; j++ {
  //内循环控制比较的次数
  for i := 0; i < len(arr)-j-1; i++ { //内层的每轮比较的次数都-1次
   if arr[i] > arr[i+1] {
    //两数比较以后进行位置交换
    arr[i], arr[i+1] = arr[i+1], arr[i]
   }
  }
 }
 fmt.Println("----排序结束----")
 fmt.Println(arr)
}
//输出结果如下
初始值为: [34 61 22 75 42]
----排序结束----
[22 34 42 61 75]


控制台随机输入几个数,进行冒泡排序


package main
import "fmt"
var (
 numbers int       //指定输入的数
 arr     = []int{} //空数组
)
func main() {
 for i := 0; i < 5; i++ {
  fmt.Printf("请输入第%d个数字:", i+1)
  fmt.Scan(&numbers)
  arr = append(arr, numbers)  //使用append进行添加数组元素
  fmt.Println("添加成功")
 }
 fmt.Println("初始值为:", arr)
 //外循环控制比较的轮数
 for j := 0; j < len(arr)-1; j++ {
  //内循环控制比较的次数
  for i := 0; i < len(arr)-j-1; i++ { //内层的每轮比较的次数都-1次
   if arr[i] > arr[i+1] {
    //两数比较以后进行位置交换
    arr[i], arr[i+1] = arr[i+1], arr[i]
   }
  }
 }
 fmt.Println("----排序结束----")
 fmt.Println(arr)
}
//输出结果如下
请输入第1个数字:88
添加成功
请输入第2个数字:99
添加成功
请输入第3个数字:50
添加成功
请输入第4个数字:146
添加成功
请输入第5个数字:48
添加成功
初始值为: [88 99 50 146 48]
----排序结束----
[48 50 88 99 146]

 

五、多维数组


  • Go 语言支持多维数组,如下

//常用的多维数组声明方式:

var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type


//三维的整型数组:

var threedim [5][10][4]int


1. 二维数组


二维数组是最简单的多维数组,二维数组本质上是由一维数组组成的。

  • 二维数组定义方式如下

var arrayName [ x ][ y ] variable_type



  • variable_type 为 Go 语言的数据类型,arrayName 为数组名,二维数组可认为是一个表格,x 为行,y 为列

下图演示了一个二维数组 a 为三行四列:

2387773-20220328125810354-2060810095.png


二维数组中的元素可通过 a[i][j]来访问

package main
import "fmt"
func main() {
 //创建数组
 numbers := [][]int{}
 //使用 append() 函数向空的二维数组添加两行一维数组
 x := []int{1, 2, 3}
 y := []int{4, 5, 6}
 numbers = append(numbers, x)
 numbers = append(numbers, y)
 //显示两行数据,查看二维数组中的第一个数组和第二个数组
 fmt.Printf("二维数组中的第1个一维数组为: %v\n", numbers[0])
 fmt.Printf("二维数组中的第1个一维数组为: %v\n", numbers[1])
 fmt.Printf("二维数组中的第1个一维数组的第一个元素为: ")
 fmt.Println(numbers[0][0]) //numbers[0]里面的第一个元素[0],为1
}
//输出结果如下
二维数组中的第1个一维数组为: [1 2 3]
二维数组中的第1个一维数组为: [4 5 6]
二维数组中的第1个一维数组的第一个元素为: 1

2. 初始化二维数组


多维数组可通过大括号来初始值,以下为一个3行4列的二维数组

a := [3][4]int {
 {0,1,2,3},   //第1行索引为0
 {4,5,6,7},   //第2行索引为1
 {8,9,10,11},  //第3行索引为2
 }



注意,上面的代码中倒数第二行的 }必须有逗号,因为最后一行的 }不能单独一行,也可以写成下面这样


a := [3][4]int {
 {0,1,2,3},   //第1行索引为0
 {4,5,6,7},   //第2行索引为1
 {8,9,10,11}}  //第3行索引为2


示例,初始化一个2行2列的二维数组


package main
import "fmt"
func main() {
 //创建二维数组
 list := [2][2]string{}
 //向二维数组中添加元素
 list[0][0] = "你好" //第1个一维数组中的第1个元素
 list[0][1] = "欢迎" //第1个一维数组中的第2个元素
 list[1][0] = "来到" //第2个一维数组中的第1个元素
 list[1][1] = "南京" //第2个一维数组中的第2个元素
 //输出结果
 fmt.Println(list)
}
//输出结果如下
[[你好 欢迎] [来到 南京]]


3. 访问二维数组


  • 二维数组通过指定坐标来访问。如数组中的行索引与列索引,例如:

//访问二维数组 val 第三行的第四个元素

val := a[2][3]

var value int = a[2][3]



  • 二维数组可以使用循环嵌套来输出元素
package main
import "fmt"
func main() {
 nums := [2][3]int{
  {1, 2, 3},
  {4, 5, 6},
 }
 //遍历二维数组中的每个元素
 //外层循环读取行
 for i := 0; i < 2; i++ {
  //内层循环读取列
  for j := 0; j < 3; j++ {
   fmt.Println(nums[i][j])
  }
 }
}
//输出结果如下
1
2
3
4
5
6
  • 创建各个维度元素数量不一致的多维数组


package main
import "fmt"
func main() {
 // 创建空的二维数组
 list := [][]string{}
 // 创建三一维数组,各数组长度不同
 num1 := []string{"zhang", "wang", "zhao"}
 num2 := []string{"li"}
 num3 := []string{"sun", "jin"}
 // 使用 append() 函数将一维数组添加到二维数组中
 list = append(list, num1)
 list = append(list, num2)
 list = append(list, num3)
 // 循环输出
 for i := range list {
  fmt.Printf("list: %v\n", i)
  fmt.Println(list[i])
 }
}
//输出结果如下
list: 0
[zhang wang zhao]
list: 1
[li]
list: 2
[sun jin]

 

六、向函数传递数组


如果想向函数传递数组参数,需要在函数定义时,声明形参为数组,可通过如下两种方式来声明:


1. 形参设定数组大小


void myFunction(param [10]int)
{
.
.
.
}


2. 形参未设定数组大小


void myFunction(param []int)
{
.
.
.
}

 

3. 示例


  • 函数接收整形数组参数,另一个参数指定了数组元素的个数,并求和
package main
import "fmt"
//定义数组,有5个元素
var numbers [5]int
func main() {
 numbers = [5]int{10, 20, 30, 40, 50}
 fmt.Println("元素和为:", sum(numbers))
}
func sum(arr [5]int) int {
 //定义求和的变量s
 s := 0
 //求和过程
 for i := range arr {
  s += arr[i]
 }
 return s
}
//输出结果如下
元素和为: 150
• 函数接收整形数组参数,另一个参数指定了数组元素的个数,并求出平均值
package main
import "fmt"
var (
 //数组长度为5
 nums = [5]int{10, 20, 40, 60, 80}
 avg  float32
 s    int
)
func main() {
 //数组作为参数传递给函数
 avg = sums(nums, len(nums))
 //输出返回的平均值
 fmt.Printf("平均值为: %f", avg)
}
//传入数组和他的长度,返回值的类型为float32
func sums(x [5]int, length int) float32 {
 for i := 0; i < length; i++ {
  s += x[i]
 }
 avg = float32(s) / float32(length)
 return avg
}
//输出结果如下
平均值为: 42.000000

 

总结


  • 数组的元素可以通过下标的方式来访问,下标的最大长度为数组长度-1,如果大于这个下标则会越界
  • 遍历数组的两种方法:
    ① 通过 for循环,长度可以使用len()获取
    ② 通过for range循环遍历数组,返回数组下标和对应的值;若不想要下标,可以使用空白标识符_来取代

 

相关文章
|
3天前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
4天前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
8天前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
Go 语言入门指南:切片
|
12天前
|
算法 安全 Go
公司局域网管理系统里的 Go 语言 Bloom Filter 算法,太值得深挖了
本文探讨了如何利用 Go 语言中的 Bloom Filter 算法提升公司局域网管理系统的性能。Bloom Filter 是一种高效的空间节省型数据结构,适用于快速判断元素是否存在于集合中。文中通过具体代码示例展示了如何在 Go 中实现 Bloom Filter,并应用于局域网的 IP 访问控制,显著提高系统响应速度和安全性。随着网络规模扩大和技术进步,持续优化算法和结合其他安全技术将是企业维持网络竞争力的关键。
26 2
公司局域网管理系统里的 Go 语言 Bloom Filter 算法,太值得深挖了
|
4天前
|
存储 缓存 监控
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
22 3
|
8天前
|
开发框架 前端开发 Go
eino — 基于go语言的大模型应用开发框架(二)
本文介绍了如何使用Eino框架实现一个基本的LLM(大语言模型)应用。Eino中的`ChatModel`接口提供了与不同大模型服务(如OpenAI、Ollama等)交互的统一方式,支持生成完整响应、流式响应和绑定工具等功能。`Generate`方法用于生成完整的模型响应,`Stream`方法以流式方式返回结果,`BindTools`方法为模型绑定工具。此外,还介绍了通过`Option`模式配置模型参数及模板功能,支持基于前端和用户自定义的角色及Prompt。目前主要聚焦于`ChatModel`的`Generate`方法,后续将继续深入学习。
102 7
|
4天前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
8天前
|
存储 开发框架 Devops
eino — 基于go语言的大模型应用开发框架(一)
Eino 是一个受开源社区优秀LLM应用开发框架(如LangChain和LlamaIndex)启发的Go语言框架,强调简洁性、可扩展性和可靠性。它提供了易于复用的组件、强大的编排框架、简洁明了的API、最佳实践集合及实用的DevOps工具,支持快速构建和部署LLM应用。Eino不仅兼容多种模型库(如OpenAI、Ollama、Ark),还提供详细的官方文档和活跃的社区支持,便于开发者上手使用。
74 8
|
18天前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
68 20
|
8天前
|
存储 算法 Go
Go语言实战:错误处理和panic_recover之自定义错误类型
本文深入探讨了Go语言中的错误处理和panic/recover机制,涵盖错误处理的基本概念、自定义错误类型的定义、panic和recover的工作原理及应用场景。通过具体代码示例介绍了如何定义自定义错误类型、检查和处理错误值,并使用panic和recover处理运行时错误。文章还讨论了错误处理在实际开发中的应用,如网络编程、文件操作和并发编程,并推荐了一些学习资源。最后展望了未来Go语言在错误处理方面的优化方向。

热门文章

最新文章