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

  • 本文关键字:切片 是否 GO list go
  • 更新时间 :
  • 英文 :


我有以下代码:

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

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

在 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
}

当然,这忽略了重复项,因此还有改进的余地。

@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

您似乎正在寻找集合是子集:

在Python中,它看起来像这样:

In [1]: l1 = ["a", "b", "c"]
In [2]: l2 = ["a", "c"]
In [3]: set(l2).issubset(l1)
Out[3]: True

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)
}

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

最新更新