简体   繁体   English

如何在GO中检查切片是否在切片中?

[英]How to check if a slice is inside a slice in GO?

I have the following code: 我有以下代码:

func main(){
    l1 := []string{"a", "b", "c"}
    l2 := []string {"a", "c"}
    //l2 in l1?
}

I can check this using loops and flags but Is there a simple way to check if l2 is inside l1 like python command "l2 in l1"? 我可以使用循环和标志进行检查,但是有没有一种简单的方法可以检查l2是否位于l1内部,如python命令“ l1中的l2”?

Following from How to check if a slice is inside a slice in GO? 如何在GO中检查切片内是否包含切片开始? , @Mostafa posted the following for checking if an element is in a slice: ,@ Mostafa发布了以下内容,以检查元素是否在切片中:

func contains(s []string, e string) bool {
   for _, a := range s {
        if a == e {
            return true
        }
    }
    return false
}

Now it's a matter of checking element by element: 现在只需逐个检查元素即可:

func subslice (s1 []string, s2 []string) bool {
    if len(s1) > len(s2) { return false }
    for _, e := range s1 {
        if ! contains(s2,e) {
            return false
        }
    }
    return true
}

Of course, this ignores duplicates, so there's room for improvement. 当然,这会忽略重复项,因此还有改进的空间。

@Kabanus's answer is of O(mn) time complexity. @Kabanus的答案是O(mn)时间复杂性。 Despite being slow in large scale, it only requires elemenent of both set to be == comparable, which is almost any cases. 尽管大规模运行缓慢,但几乎只需要将两者的元素设置为==可比。

But if your data is hashable, and preferably hashable by default (ie can be used as key of a map ), using an auxiliary map is a much more efficient way: 但是,如果您的数据是可哈希的,并且默认情况下最好是可哈希的(即可以用作map键),那么使用辅助映射是一种更有效的方法:

package main

import (
    "fmt"
)

type Universe map[string]bool

func NewUniverse(s []string) Universe {
    u:=make(Universe)
    for _,i:=range s {
        u[i]=true
    }
    return u
}

func (u Universe) CountainSet(s []string) bool {
    for _,i:=range s {
        if !u[i] {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println(NewUniverse([]string{"a","b","c"}).CountainSet([]string{"a","c"}))
}

Dealing with duplicate is very trivial: change map[string]bool to map[string]int and compare element count. 处理重复项非常简单:将map [string] bool更改为map [string] int并比较元素计数。

Playground: https://play.golang.org/p/pdM4DO3UO2e 游乐场: https : //play.golang.org/p/pdM4DO3UO2e

It appears that you are looking for set issubset: 看来您正在寻找set issubset:

In Python it would look like this: 在Python中,它看起来像这样:

In [1]: l1 = ["a", "b", "c"]

In [2]: l2 = ["a", "c"]

In [3]: set(l2).issubset(l1)
Out[3]: True

The most similar version of this in go uses golang-set and looks like this: go中最相似的版本使用golang-set ,看起来像这样:

package main

import (
    "fmt"

    "github.com/deckarep/golang-set"
)

func sliceToSet(mySlice []string) mapset.Set {
    mySet := mapset.NewSet()
    for _, ele := range mySlice {
        mySet.Add(ele)
    }   
    return mySet
}

func main() {

    l1 := []string{"a", "b", "c"}
    l2 := []string{"a", "c"}

    s1 := sliceToSet(l1)
    s2 := sliceToSet(l2)

    result := s2.IsSubset(s1)

    fmt.Println(result)
}

The time complexity of above approach is linear time. 上述方法的时间复杂度是线性时间。 The time complexity of issubset itself is O(n), where n is length of a set we are checking if subset, in this case s2 . issubset本身的时间复杂度为O(n),其中n是要检查子集的集合的长度,在这种情况下为s2 There is also conversion from slice to set that is also linear time. 从切片到集合的转换也是线性时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM