从两个数组/切片中获取交集和排除项的最有效方法是什么?

给定两个数组或切片,例如:


a := []int{1, 2, 3, 4, 5}

b := []int{3, 4, 5, 6, 7, 8, 9}

切片可能未排序,顺序无关紧要。


计算值的最有效方法是什么,这样您最终得到两个切片的公共元素,并且剩余元素存在于一个而不是另一个,即对于上面给出的两个数组,返回值将是:


common := []int{3, 4, 5}

inAButNotB := []int{1, 2}

inBButNotA := []int{6, 7, 8, 9}

很容易计算交集,将一个切片转换为地图,然后迭代该切片以查看值是否存在。有没有办法在同一个循环中计算其他两个值?


小怪兽爱吃肉
浏览 81回答 1
1回答

婷婷同学_

O(len(a) + len(b))是有效的。例如,package mainimport (    "fmt")func main() {    a := []int{1, 2, 3, 4, 5}    b := []int{3, 4, 5, 6, 7, 8, 9}    fmt.Println(a)    fmt.Println(b)    m := make(map[int]uint8)    for _, k := range a {        m[k] |= (1 << 0)    }    for _, k := range b {        m[k] |= (1 << 1)    }    var inAAndB, inAButNotB, inBButNotA []int    for k, v := range m {        a := v&(1<<0) != 0        b := v&(1<<1) != 0        switch {        case a && b:            inAAndB = append(inAAndB, k)        case a && !b:            inAButNotB = append(inAButNotB, k)        case !a && b:            inBButNotA = append(inBButNotA, k)        }    }    fmt.Println(inAAndB)    fmt.Println(inAButNotB)    fmt.Println(inBButNotA)}游乐场:https://play.golang.org/p/RvGaC9Wfjiv输出:[1 2 3 4 5][3 4 5 6 7 8 9][3 4 5][1 2][8 6 7 9]Go 编程语言规范&    bitwise AND            integers|    bitwise OR             integers^    bitwise XOR            integers&^   bit clear (AND NOT)    integers<<   left shift             integer << unsigned integer>>   right shift            integer >> unsigned integer我们有 8 位用于uint8. Bit 0 ( 1 << 0, 1 shift left 0) isa和 bit 1 ( 1 << 1; 1 shift left 1) is b。对于uint8位,00000001是a,00000010是b,00000011是a和b,并且00000000是 nether anor b。操作员|设置位,&操作员读取位。Go 编程语言规范地图类型映射是一种类型的无序元素组,称为元素类型,由一组另一种类型的唯一键索引,称为键类型。必须为键类型的操作数完全定义比较运算符 == 和 !=;因此键类型不能是函数、映射或切片。如果键类型是接口类型,则必须为动态键值定义这些比较运算符;失败将导致运行时恐慌。该算法适用于其元素可以是映射键的任何切片类型。必须为键类型的操作数完全定义比较运算符 == 和 !=。
打开App,查看更多内容
随时随地看视频慕课网APP