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

时间:2018-01-31 19:26:31

标签: list go

我有以下代码:

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

我可以使用循环和标志来检查这个但是有一种简单的方法可以检查l2是否在l1里面,如python命令" l2在l1"?

3 个答案:

答案 0 :(得分:3)

How to check if a slice is inside a slice in GO?开始,@ Mostafa发布了以下内容,用于检查元素是否在切片中:

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

现在要逐个元素地检查:

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
}

当然,这会忽略重复,所以还有改进的余地。

答案 1 :(得分:2)

@ Kabanus的回答是O(mn)时间复杂度。尽管大规模的速度很慢,但它只要求两者的等值==具有可比性,几乎在任何情况下都是如此。

但是如果你的数据是可以删除的,并且默认情况下最好是可以删除的(即可以用作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"}))
}

处理重复非常简单:将map [string] bool更改为map [string] int并比较元素数。

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

答案 2 :(得分:1)

看来你正在寻找set issubset:

在Python中它看起来像这样:

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

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

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

最常用的版本使用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)
}

上述方法的时间复杂度是线性时间。 issubset本身的时间复杂度是O(n),其中n是我们正在检查子集的集合的长度,在这种情况下是s2。还有从切片到设置的转换也是线性时间。