一.交集
1.两个切片的交集
采用map的实现取两个切片的交集。其中如果mp[s]访问成功,即有s这个键,ok为true,否则ok为false。以string类型为例:
func intersect(a []string, b []string) []string {
inter := make([]uint, 0)
mp := make(map[string]bool)
for _, s := range a {
if _, ok := mp[s]; !ok {
mp[s] = true
}
}
for _, s := range b {
if _, ok := mp[s]; ok {
inter = append(inter, s)
}
}
return inter
}
调试:
a := []string{"1", "2", "3", "4", "5", "1", "66", "6"}
b := []string{"6", "7", "", "4", "5", "2"}
for _, s := range intersect(a, b) {
println(s)
}
输出:
6
4
5
2
2.多个切片的交集
主要思路和2个切片时相同,小区别就是把,map的value类型改为了int用于计数,最后通过计数和传进的lists的长度关系判断是否需要该元素。以uint类型的切片为例:
// intersect 获取交集
func intersect(lists ...[]uint) []uint {
var inter []uint
mp := make(map[uint]int)
l := len(lists)
// 特判 只传了0个或者1个切片的情况
if l == 0 {
return make([]uint, 0)
}
if l == 1 {
for _, s := range lists[0] {
if _, ok := mp[s]; !ok {
mp[s] = 1
inter = append(inter, s)
}
}
return inter
}
// 一般情况
// 先使用第一个切片构建map的键值对
for _, s := range lists[0] {
if _, ok := mp[s]; !ok {
mp[s] = 1
}
}
// 除去第一个和最后一个之外的list
for _, list := range lists[1 : l-1] {
for _, s := range list {
if _, ok := mp[s]; ok {
// 计数+1
mp[s]++
}
}
}
for _, s := range lists[l-1] {
if _, ok := mp[s]; ok {
if mp[s] == l-1 {
inter = append(inter, s)
}
}
}
return inter
}
调试:
a := []uint{1, 6, 5, 1, 5, 1, 69, 1, 2}
b := []uint{1, 2, 3}
c := []uint{2, 3, 4, 5, 6}
d := intersect(a, b, c)
for _, i := range d {
println(i)
}
输出:
2
二.差集
首先从将第一个切片中的元素保存到map中,然后遍历第二个切片。如果该key存在,则删除该key。
// minus 获取差集
func minus(a []uint, b []uint) []uint {
var inter []uint
mp := make(map[uint]bool)
for _, s := range a {
if _, ok := mp[s]; !ok {
mp[s] = true
}
}
for _, s := range b {
if _, ok := mp[s]; ok {
delete(mp, s)
}
}
for key := range mp {
inter = append(inter, key)
}
return inter
}
调试:
a := []uint{1, 6, 5, 1, 5, 1, 69, 1, 2}
b := []uint{1, 2, 3}
d := minus(a, b)
for _, i := range d {
println(i)
}
输出:
6
5
69