我有以下代码:
func main(){
l1 := []string{"a", "b", "c"}
l2 := []string {"a", "c"}
//l2 in l1?
}
Run Code Online (Sandbox Code Playgroud)
我可以使用循环和标志来检查这一点,但是有没有一种简单的方法来检查 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
}
Run Code Online (Sandbox Code Playgroud)
现在需要逐个元素检查:
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
}
Run Code Online (Sandbox Code Playgroud)
当然,这会忽略重复项,因此还有改进的空间。
@Kabanus 的答案是 O(mn) 时间复杂度。尽管在大规模上速度很慢,但它只需要两个集合的元素具有==可比性,这几乎是任何情况。
但是如果你的数据是可散列的,并且最好是默认可散列的(即可以用作 a 的键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"}))
}
Run Code Online (Sandbox Code Playgroud)
处理重复非常简单:将map[string]bool 更改为map[string]int 并比较元素计数。
游乐场: https: //play.golang.org/p/pdM4DO3UO2e