当前位置: 首页 > 面试题库 >

如何在golang中获得两个切片的交集?

宋飞掣
2023-03-14
问题内容

有什么有效的方法来获取Go中两个切片的交集吗?

我想避免嵌套for循环之类的解决方案

slice1 := []string{"foo", "bar","hello"}
slice2 := []string{"foo", "bar"}

intersection(slice1, slice2)
=> ["foo", "bar"]

字符串顺序无关紧要


问题答案:

是的,有几种不同的解决方法。.这是一个可以优化的示例。

package main

import "fmt"

func intersection(a []string, b []string) (inter []string) {
    // interacting on the smallest list first can potentailly be faster...but not by much, worse case is the same
    low, high := a, b
    if len(a) > len(b) {
        low = b
        high = a
    }

    done := false
    for i, l := range low {
        for j, h := range high {
            // get future index values
            f1 := i + 1
            f2 := j + 1
            if l == h {
                inter = append(inter, h)
                if f1 < len(low) && f2 < len(high) {
                    // if the future values aren't the same then that's the end of the intersection
                    if low[f1] != high[f2] {
                        done = true
                    }
                }
                // we don't want to interate on the entire list everytime, so remove the parts we already looped on will make it faster each pass
                high = high[:j+copy(high[j:], high[j+1:])]
                break
            }
        }
        // nothing in the future so we are done
        if done {
            break
        }
    }
    return
}

func main() {
    slice1 := []string{"foo", "bar", "hello", "bar"}
    slice2 := []string{"foo", "bar"}
    fmt.Printf("%+v\n", intersection(slice1, slice2))
}

现在上面定义的交集方法将只运行在slicesstrings,比如你的例子。您可以在理论上创建一个定义,这个样子的func intersection(a []interface, b []interface) (inter []interface),但是你会依靠反射和类型转换,这样就可以比较,这将增加延迟和使您的代码更难阅读。对于您关心的每种类型,维护和阅读以编写单独的函数可能更容易。

func intersectionString(a []string, b []string) (inter []string)

func intersectionInt(a []int, b []int) (inter []int)

func intersectionFloat64(a []Float64, b []Float64) (inter []Float64),..ect

然后,您可以创建自己的包并在确定要实现的方式后重用。

package intersection

func String(a []string, b []string) (inter []string)

func Int(a []int, b []int) (inter []int)

func Float64(a []Float64, b []Float64) (inter []Float64)


 类似资料:
  • 问题内容: 提取切片的最后一个元素的Go方法是什么? 上面的解决方案有效,但看起来很尴尬。 问题答案: 仅读取切片的最后一个元素: 要删除它: 参见此页面有关切片技巧

  • 我有一个大小未知的数组,我想获取该数组的一个切片,并将其转换为静态大小的数组: 我该怎么做?

  • 问题内容: 我正在使用反射包来获取任意数组的类型,但是 如何从数组中获取类型?我知道如何从价值中获取价值。 http://play.golang.org/p/sNw8aL0a5f 问题答案: 更改: 至: 顺便说一句,不是一个数组而是一个整数 切片 。

  • 问题内容: 我最近学习了Go语言,现在对以下代码感到困惑: 结果: 问题答案: c是从数组中获取的一个切片b。这不是副本,而只是的两个前两个元素的窗口b。 由于b容量为5,c可以扩展到其他3个位置(实际上,它会创建一个新的切片,但位于内存中的同一位置)。 切片的最大容量是底层数组的容量减去切片在数组中起始位置的大小: func main() { b := make([]int, 0, 5) c :

  • 如果这两个矩阵不是无序的,长度相同,那么下面的代码应该可以工作,并且是有效的。 我的一个老练的解决方案是将我要用于匹配的每个矩阵的各个列串联起来。在本例中,我将使用所有列。 这就是我正在寻找的结果,但我想知道是否有更优雅的东西,比如%中的向量函数

  • 问题内容: 我正在尝试将切片和切片结合起来。如何在Go中执行此操作? 我试过了: 但得到: 但是,文档似乎表明这是可能的,我想念的是什么? 问题答案: 在第二个切片之后添加点: 就像任何其他可变参数函数一样。