golang实现获取切片的交集和差集

2024-04-20 03:36

本文主要是介绍golang实现获取切片的交集和差集,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.交集

1.两个切片的交集

采用map实现取两个切片的交集,其中如果map[key]访问成功,即有key这个键,ok为true,否则ok为false。,以string类型为例:

//a 切片, b 切片
func intersect(a []string, b []string) []string {//初始化一个切片inter := make([]uint, 0)/初始化一个map[string]bool  : string为a切片valmp := make(map[string]bool)for _, value := range a {  //循环a切片if _, ok := mp[value ]; !ok {  //判断mp切片是否存在,不存在则设置key-valuemp[value] = true}}for _, val := range b {  //循环b切片if _, ok := mp[val]; ok {  //判断mp中是否存在b切片的值,如果存在,则append切片数据到inter中inter = append(inter, val)}}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 []uintmp := 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] = 1inter = append(inter, s)}}return inter}// 一般情况// 先使用第一个切片构建map的键值对for _, s := range lists[0] {if _, ok := mp[s]; !ok {mp[s] = 1}}// 除去第一个和最后一个之外的listfor _, list := range lists[1 : l-1] {for _, s := range list {if _, ok := mp[s]; ok {// 计数+1mp[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
方法二

MultipleIntersect 函数可以接受任意数量的切片作为参数,并返回它们的交集,它通过递归调用Intersect函数来实现这一点,Intersect函数用于两个切片的交集计算,这里使用了一个辅助map来优化搜索效率

package mainimport ("fmt""reflect"
)// 获取两个切片的交集
func Intersect(a, b []int) []int {m := make(map[int]bool)for _, v := range a {m[v] = true}var intersection []intfor _, v := range b {if m[v] {intersection = append(intersection, v)}}return intersection
}// 获取多个切片的交集
func MultipleIntersect(s ...[]int) []int {if len(s) == 0 {return nil}result := s[0]for i := 1; i < len(s); i++ {result = Intersect(result, s[i])}return result
}func main() {slice1 := []int{1, 2, 3, 4, 5}slice2 := []int{4, 5, 6, 7, 8}slice3 := []int{7, 8, 9, 10}intersection := MultipleIntersect(slice1, slice2, slice3)fmt.Println(intersection) // 输出交集: [8 7]
}

二.差集

1.两个切片的差集

方法一

从将第一个切片中的元素保存到map中,然后遍历第二个切片,如果该key存在,则删除该key

// minus 获取差集
func minus(a []uint, b []uint) []uint {var inter []uintmp := 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
方法二

可以通过遍历一个切片,然后检查元素是否存在于其他切片中来获取多个切片的差集,以下是一个简单的函数,用于获取两个或多个切片的差集

package mainimport ("fmt"
)// 获取两个切片的差集
func Difference(s1, s2 []int) []int {m := make(map[int]bool)// 将s1中的元素设置为出现在map中for _, v := range s1 {m[v] = true}// 遍历s2,如果s2中的元素不在map中,则加入结果切片var diff []intfor _, v := range s2 {if !m[v] {diff = append(diff, v)}}return diff
}func main() {slice1 := []int{1, 2, 3, 4, 5}slice2 := []int{4, 5, 6, 7, 8}difference := Difference(slice1, slice2)fmt.Println("Difference:", difference) 
}

2.多个切片的差集

如果需要获取更多切片的差集,可以对上述函数进行递归或者使用Difference函数的结果作为输入来连续调用

// 获取多个切片的差集
func DifferenceMultiple(slices ...[]int) []int {result := slices[0]for _, slice := range slices[1:] {result = Difference(result, slice)}return result
}func main() {slice1 := []int{1, 2, 3, 4, 5}slice2 := []int{4, 5, 6, 7, 8}slice3 := []int{1, 2, 9, 10}difference := DifferenceMultiple(slice1, slice2, slice3)fmt.Println("Difference:", difference) 
}

这篇关于golang实现获取切片的交集和差集的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/919200

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too