mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	docs(array): sample code for golang
本次提交包含如下示例代码。
- 遍历数组;
- 初始化数组;
- 扩展数组长度;
- 在数组中查找指定元素;
- 随机返回一个数组元素;
- 删除索引 index 处元素;
- 在数组的索引 index 处插入元素 num。
所有数组约定长度为 5。原因如下:
在 goalng 中,必须声明数组的长度,例如:nums := [5]int{1,2,3,4,5}。如果不声明长度,则被称为切片。
使用的注释没有按照 golang 的编程惯例,而是倾向于使用文档上下文的注释约定。
所以所有函数注释均使用了 `/* ... */`,而不是双斜杠 `//`。
			
			
This commit is contained in:
		
							
								
								
									
										83
									
								
								codes/go/chapter_array_and_linkedlist/array.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								codes/go/chapter_array_and_linkedlist/array.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
			
		||||
package chapter_array_and_linkedlist
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ExpectSize 预期大小。 在 Go 中,声明数组长度必须是常量表达式,
 | 
			
		||||
// 所以这里我们约定,扩展后的长度为 6
 | 
			
		||||
const ExpectSize = 6
 | 
			
		||||
 | 
			
		||||
/* 随机返回一个数组元素 */
 | 
			
		||||
func randomAccess(nums [5]int) (ans int) {
 | 
			
		||||
	// 在区间 [0, nums.length) 中随机抽取一个数字
 | 
			
		||||
	randomIndex := rand.Intn(len(nums))
 | 
			
		||||
	// 获取并返回随机元素
 | 
			
		||||
	ans = nums[randomIndex]
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 扩展数组长度 */
 | 
			
		||||
func extend(nums [5]int) [ExpectSize]int {
 | 
			
		||||
	// 初始化一个扩展长度后的数组
 | 
			
		||||
	var res [ExpectSize]int
 | 
			
		||||
	// 将原数组中的所有元素复制到新数组
 | 
			
		||||
	for i := 0; i < len(nums); i++ {
 | 
			
		||||
		res[i] = nums[i]
 | 
			
		||||
	}
 | 
			
		||||
	// 返回扩展后的新数组
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 在数组的索引 index 处插入元素 num */
 | 
			
		||||
func insert(nums *[5]int, num int, index int) {
 | 
			
		||||
	// 把索引 index 以及之后的所有元素向后移动一位
 | 
			
		||||
	// 如果超出了数组长度,会被直接舍弃
 | 
			
		||||
	for i := len(nums) - 1; i > index; i-- {
 | 
			
		||||
		nums[i] = nums[i-1]
 | 
			
		||||
	}
 | 
			
		||||
	// 将 num 赋给 index 处元素
 | 
			
		||||
	nums[index] = num
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 删除索引 index 处元素 */
 | 
			
		||||
func remove(nums *[5]int, index int) {
 | 
			
		||||
	// 越界检查
 | 
			
		||||
	if index >= len(nums) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// 把索引 index 之后的所有元素向前移动一位
 | 
			
		||||
	for i := index; i < len(nums); i++ {
 | 
			
		||||
		if i+1 >= len(nums) {
 | 
			
		||||
			nums[len(nums)-1] = 0
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		nums[i] = nums[i+1]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 遍历数组 */
 | 
			
		||||
func traverse(nums [5]int) {
 | 
			
		||||
	var count int
 | 
			
		||||
	// 通过索引遍历数组
 | 
			
		||||
	for i := 0; i < len(nums); i++ {
 | 
			
		||||
		count++
 | 
			
		||||
	}
 | 
			
		||||
	// 直接遍历数组
 | 
			
		||||
	for index, val := range nums {
 | 
			
		||||
		fmt.Printf("index:%v value:%v\n", index, val)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 在数组中查找指定元素 */
 | 
			
		||||
func find(nums [5]int, target int) (ans int) {
 | 
			
		||||
	ans = -1
 | 
			
		||||
	for i := 0; i < len(nums); i++ {
 | 
			
		||||
		if nums[i] == target {
 | 
			
		||||
			ans = i
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								codes/go/chapter_array_and_linkedlist/array_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								codes/go/chapter_array_and_linkedlist/array_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
			
		||||
package chapter_array_and_linkedlist
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestInitArray(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	var arr [5]int
 | 
			
		||||
	for _, v := range arr {
 | 
			
		||||
		if v != 0 {
 | 
			
		||||
			t.Fatalf("array init exception")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRandomAccess(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	min, max := 1, 5
 | 
			
		||||
	nums := [5]int{min, 2, 3, 4, max}
 | 
			
		||||
	ans := randomAccess(nums)
 | 
			
		||||
	if ans < min || ans > max {
 | 
			
		||||
		t.Fatalf("Expected range is greater than min: %v and less than max: %v, got ans: %v", min, max, ans)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestExtend(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	nums := [5]int{1, 2, 3, 4, 5}
 | 
			
		||||
	newNums := extend(nums)
 | 
			
		||||
	if len(newNums) != ExpectSize {
 | 
			
		||||
		t.Fatalf("Expected len: %v, got: %v", ExpectSize, len(nums))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestInsert(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	nums := [5]int{1, 2, 3, 4, 5}
 | 
			
		||||
	insert(&nums, 5, 0)
 | 
			
		||||
	if nums[0] != 5 {
 | 
			
		||||
		t.Fatalf("Expected index[0] val: 5, got: %v", nums[0])
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRemove(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	type fields struct {
 | 
			
		||||
		index  int
 | 
			
		||||
		after  [5]int
 | 
			
		||||
		before [5]int
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name   string
 | 
			
		||||
		fields fields
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "remove index[0]",
 | 
			
		||||
			fields: struct {
 | 
			
		||||
				index  int
 | 
			
		||||
				after  [5]int
 | 
			
		||||
				before [5]int
 | 
			
		||||
			}{
 | 
			
		||||
				index:  0,
 | 
			
		||||
				after:  [5]int{2, 3, 4, 5, 0},
 | 
			
		||||
				before: [5]int{1, 2, 3, 4, 5},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "remove end",
 | 
			
		||||
			fields: struct {
 | 
			
		||||
				index  int
 | 
			
		||||
				after  [5]int
 | 
			
		||||
				before [5]int
 | 
			
		||||
			}{
 | 
			
		||||
				index:  4,
 | 
			
		||||
				after:  [5]int{1, 2, 3, 4, 0},
 | 
			
		||||
				before: [5]int{1, 2, 3, 4, 5},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			v := tt.fields
 | 
			
		||||
			remove(&v.before, v.index)
 | 
			
		||||
			if !reflect.DeepEqual(v.before, v.after) {
 | 
			
		||||
				t.Errorf("remove(&v.before, v.index) = %v, want %v", v.before, v.after)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestTraverse(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	nums := [5]int{1, 2, 3, 4, 5}
 | 
			
		||||
	traverse(nums)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestFind(t *testing.T) {
 | 
			
		||||
	t.Parallel()
 | 
			
		||||
	type fields struct {
 | 
			
		||||
		target int
 | 
			
		||||
		nums   [5]int
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name   string
 | 
			
		||||
		fields fields
 | 
			
		||||
		want   int
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "element exists",
 | 
			
		||||
			fields: struct {
 | 
			
		||||
				target int
 | 
			
		||||
				nums   [5]int
 | 
			
		||||
			}{
 | 
			
		||||
				target: 1,
 | 
			
		||||
				nums:   [5]int{1, 2, 3, 4, 5},
 | 
			
		||||
			},
 | 
			
		||||
			want: 0,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "element does not exist",
 | 
			
		||||
			fields: struct {
 | 
			
		||||
				target int
 | 
			
		||||
				nums   [5]int
 | 
			
		||||
			}{
 | 
			
		||||
				target: 6,
 | 
			
		||||
				nums:   [5]int{1, 2, 3, 4, 5},
 | 
			
		||||
			},
 | 
			
		||||
			want: -1,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			v := tt.fields
 | 
			
		||||
			if got := find(v.nums, v.target); got != tt.want {
 | 
			
		||||
				t.Errorf("find(v.nums, v.target) = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -43,7 +43,9 @@ comments: true
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
 | 
			
		||||
    /* 初始化数组 */
 | 
			
		||||
    var arr [5]int // {0, 0, 0, 0, 0}
 | 
			
		||||
    nums := [5]int{1, 3, 2, 5, 4}
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -133,7 +135,14 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
    
 | 
			
		||||
    /* 随机返回一个数组元素 */
 | 
			
		||||
    func randomAccess(nums [5]int) (ans int) {
 | 
			
		||||
        // 在区间 [0, nums.length) 中随机抽取一个数字
 | 
			
		||||
        randomIndex := rand.Intn(len(nums))
 | 
			
		||||
        // 获取并返回随机元素
 | 
			
		||||
        ans = nums[randomIndex]
 | 
			
		||||
        return
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -236,7 +245,20 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
    
 | 
			
		||||
    // 在 Go 中,声明数组长度必须是常量表达式,
 | 
			
		||||
    // 所以这里我们约定,扩展后的长度为 6
 | 
			
		||||
    const expectSize = 6
 | 
			
		||||
    // 扩展数组长度
 | 
			
		||||
    func extend(nums [5]int) [expectSize]int {
 | 
			
		||||
        // 初始化一个扩展长度后的数组
 | 
			
		||||
        var res [expectSize]int
 | 
			
		||||
        // 将原数组中的所有元素复制到新数组
 | 
			
		||||
        for i := 0; i < len(nums); i++ {
 | 
			
		||||
            res[i] = nums[i]
 | 
			
		||||
        }
 | 
			
		||||
        // 返回扩展后的新数组
 | 
			
		||||
        return res
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -370,7 +392,32 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
    
 | 
			
		||||
    /* 在数组的索引 index 处插入元素 num */
 | 
			
		||||
    func insert(nums [5]int, num int, index int) {
 | 
			
		||||
        // 把索引 index 以及之后的所有元素向后移动一位
 | 
			
		||||
        // 如果超出了数组长度,会被直接舍弃
 | 
			
		||||
        for i := len(nums) - 1; i > index; i-- {
 | 
			
		||||
            nums[i] = nums[i-1]
 | 
			
		||||
        }
 | 
			
		||||
        // 将 num 赋给 index 处元素
 | 
			
		||||
        nums[index] = num
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 删除索引 index 处元素 */
 | 
			
		||||
    func remove(nums [5]int, index int) {
 | 
			
		||||
        // 越界检查
 | 
			
		||||
        if index >= len(nums) {
 | 
			
		||||
            return
 | 
			
		||||
        }
 | 
			
		||||
        // 把索引 index 之后的所有元素向前移动一位
 | 
			
		||||
        for i := index; i < len(nums); i++ {
 | 
			
		||||
            if i+1 >= len(nums) {
 | 
			
		||||
                nums[len(nums)-1] = 0
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
            nums[i] = nums[i+1]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -499,7 +546,18 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
    
 | 
			
		||||
    /* 遍历数组 */
 | 
			
		||||
    func traverse(nums [5]int) {
 | 
			
		||||
        var count int
 | 
			
		||||
        // 通过索引遍历数组
 | 
			
		||||
        for i := 0; i < len(nums); i++ {
 | 
			
		||||
            count++
 | 
			
		||||
        }
 | 
			
		||||
        // 直接遍历数组
 | 
			
		||||
        for index, val := range nums {
 | 
			
		||||
            fmt.Printf("index:%d value:%d\n", index, val)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -604,7 +662,17 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
=== "Go"
 | 
			
		||||
 | 
			
		||||
    ```go title="array.go"
 | 
			
		||||
    
 | 
			
		||||
    /* 在数组中查找指定元素 */
 | 
			
		||||
    func find(nums [5]int, target int) (ans int){
 | 
			
		||||
        ans = -1
 | 
			
		||||
        for i := 0; i < len(nums); i++ {
 | 
			
		||||
            if nums[i] == target {
 | 
			
		||||
                ans = i
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return
 | 
			
		||||
    }
 | 
			
		||||
    ```
 | 
			
		||||
 | 
			
		||||
=== "JavaScript"
 | 
			
		||||
@ -660,4 +728,4 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
 | 
			
		||||
 | 
			
		||||
**二分查找。** 例如前文查字典的例子,我们可以将字典中的所有字按照拼音顺序存储在数组中,然后使用与日常查纸质字典相同的“翻开中间,排除一半”的方式,来实现一个查电子字典的算法。
 | 
			
		||||
 | 
			
		||||
**深度学习。** 神经网络中大量使用了向量、矩阵、张量之间的线性代数运算,这些数据都是以数组的形式构建的。数组是神经网络编程中最常使用的数据结构。
 | 
			
		||||
**深度学习。** 神经网络中大量使用了向量、矩阵、张量之间的线性代数运算,这些数据都是以数组的形式构建的。数组是神经网络编程中最常使用的数据结构。
 | 
			
		||||
		Reference in New Issue
	
	Block a user