Go算法常用函数整理
使用 Go 语言编写算法题时,掌握一些常用的函数和用法可以大大提高效率。
1. 排序 (slices 包):
-
slices.Sort(x []T)
: 对切片x
进行升序排序。需要 Go 1.18+ 版本。T
需要实现constraints.Ordered
接口,例如int
,int64
,float64
,string
等。注意:这个函数在之前的版本里使用sort.Slice
,现在推荐使用slices.Sort
。 -
slices.SortFunc(x []T, less func(a, b T) bool)
: 使用自定义的比较函数less
对切片x
进行排序。这个函数在之前的版本里使用sort.Slice
,现在推荐使用slices.SortFunc
。import "slices"nums := []int{3, 1, 4, 1, 5, 9, 2, 6} slices.Sort(nums) // 升序排序 println(nums) // 输出:[1 1 2 3 4 5 6 9]strs := []string{"apple", "banana", "orange"} slices.Sort(strs) println(strs) // 输出: [apple banana orange]// 自定义排序(按字符串长度降序) slices.SortFunc(strs, func(a, b string) bool {return len(a) > len(b) }) println(strs) // 输出:[banana orange apple]
-
slices.Max(x []T)
:返回切片x中的最大值。package mainimport ("fmt""slices" )func main() {numbers := []int{0, 42, -10, 8}fmt.Println(slices.Max(numbers)) }
输出:42
-
slices.Min(x []T)
:返回切片x中的最小值。(用法同Max一致) -
slices.Reverse(x []T)
:反转切片中的元素。package mainimport ("fmt""slices" )func main() {names := []string{"alice", "Bob", "VERA"}slices.Reverse(names)fmt.Println(names) }
输出:
[VERA Bob alice]
-
slices.Equal(s1, s2 []T) bool
:判断两个切片是否相等:长度相同且所有元素相等。 如果长度不同,Equal 返回 false。 否则,将按索引递增的顺序比较元素,比较在第一对不相等时停止。 空片和零片被视为相等。 浮点 NaN 不视为相等。
2. 数学运算 (math 包):
- 内建的**
max/min
**函数:返回两个数中的最大值/最小值。 math.Abs(x float64)
: 返回x
的绝对值。math.Max(x, y float64)
/math.Min(x, y float64)
: 返回x
和y
中的最大值/最小值。math.Pow(x, y float64)
: 返回x
的y
次方。math.Sqrt(x float64)
: 返回x
的平方根。math.Ceil(x float64)
/math.Floor(x float64)
: 返回不小于/不大于x
的最小/最大整数。
3. 字符串操作 (strings 包):
strings.Split(s, sep string)
: 将字符串s
按分隔符sep
分割成字符串切片。strings.Join(elems []string, sep string)
: 将字符串切片elems
用分隔符sep
连接成一个字符串。strings.Contains(s, substr string)
: 判断字符串s
是否包含子串substr
。strings.HasPrefix(s, prefix string)
/strings.HasSuffix(s, suffix string)
: 判断字符串s
是否以prefix
/suffix
开头/结尾。strconv.Atoi(s string)
: 将字符串s
转换为整数。strconv.Itoa(i int)
: 将整数i
转换为字符串。
4. 切片操作:
append(slice []T, elems ...T)
: 向切片slice
追加元素。len(slice)
: 获取切片长度。cap(slice)
: 获取切片容量。- 切片截取:
slice[i:j]
截取从索引i
到j-1
的元素。
5. 堆 (container/heap 包):
Go 的 container/heap
包提供了堆的实现,常用于 Top K 问题、优先队列等。
import ("container/heap"
)// 定义一个堆的类型
type IntHeap []intfunc (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } // 小根堆
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }func (h *IntHeap) Push(x any) {*h = append(*h, x.(int))
}func (h *IntHeap) Pop() any {old := *hn := len(old)x := old[n-1]*h = old[0 : n-1]return x
}// 使用
h := &IntHeap{2, 1, 5}
heap.Init(h) // 初始化堆
heap.Push(h, 3) // 推入元素
println(heap.Pop(h).(int)) // 弹出堆顶元素 (输出 1)
6. 哈希表 (map):
Go 的 map
提供了高效的哈希表实现。
m := make(map[string]int) // 创建一个 string 到 int 的映射
m["apple"] = 1
m["banana"] = 2
val, ok := m["apple"] // 获取值,ok 表示键是否存在
if ok {println(val) // 输出 1
}
delete(m, "apple") // 删除键值对
7. 链表 (container/list 包):
虽然切片在很多情况下已经足够使用,但如果需要频繁进行插入和删除操作,可以使用 container/list
包提供的双向链表。
8. 位运算:
位运算在某些算法中可以提高效率,例如:
&
:按位与|
:按位或^
:按位异或<<
:左移>>
:右移
9. 其他常用技巧:
- 使用
make
初始化切片和 map, 避免nil
指针异常。 - 使用 range 遍历切片和 map。
- 注意边界条件和空输入。
- 使用 defer 进行资源清理。