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

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import