这是两切片求交的最佳方法,时间复杂度太低。 时间复杂性:时间复杂度O(m+n) m =第一切片长度。 n =第二切片长度。
func intersection(s1, s2 []string) (inter []string) {
hash := make(map[string]bool)
for _, e := range s1 {
hash[e] = true
}
for _, e := range s2 {
// If elements present in the hashmap then append intersection list.
if hash[e] {
inter = append(inter, e)
}
}
//Remove dups from slice.
inter = removeDups(inter)
return
}
//Remove dups from slice.
func removeDups(elements []string)(nodups []string) {
encountered := make(map[string]bool)
for _, element := range elements {
if !encountered[element] {
nodups = append(nodups, element)
encountered[element] = true
}
}
return
}
first := []string{"one", "two", "three", "four"}
second := []string{"two", "four"}
result := intersection(first, second) // or intersection(second, first)
func intersection(first, second []string) []string {
out := []string{}
bucket := map[string]bool{}
for _, i := range first {
for _, j := range second {
if i == j && !bucket[i] {
out = append(out, i)
bucket[i] = true
}
}
}
return out
}
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))
}
现在,上面定义的交集方法将只对strings的slices进行操作,就像您的示例一样。理论上,您可以创建类似于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)等 然后,您可以创建自己的包,并在确定要如何实现它后重用它。
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)
7条答案
按热度按时间h79rfbju1#
How do I get the intersection between two arrays as a new array?
A
中的每个元素与B
中的每个元素进行比较(O(n^2)
)O(n)
)A
并执行优化交集(O(n*log(n))
)所有这些都在这里实现
https://github.com/juliangruber/go-intersect
iqxoj9l92#
这是两切片求交的最佳方法,时间复杂度太低。
时间复杂性:时间复杂度O(m+n)
m =第一切片长度。
n =第二切片长度。
ndasle7k3#
简单、通用和多切片!(Go 1.18)
时间复杂性:可以是线性的
Playground:https://go.dev/play/p/l5-4PkEw2xp
zaqlnxep4#
如果你的
[]string
中没有空格,也许你需要这段简单的代码:yfjy0ee75#
试试看
https://go.dev/play/p/eGGcyIlZD6y
wmtdaxz36#
https://github.com/viant/toolbox/blob/a46fd679bbc5d07294b1d1b646aeacd44e2c7d50/collections.go#L869-L920
另一个时间复杂度为O(m+n)的解决方案,它使用哈希Map。它与这里讨论的其他解决方案相比有两个不同之处。
nvbavucw7#
是的,有几种不同的方法来实现它。这里有一个可以优化的例子。
现在,上面定义的交集方法将只对
strings
的slices
进行操作,就像您的示例一样。理论上,您可以创建类似于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)
等然后,您可以创建自己的包,并在确定要如何实现它后重用它。