doulongsha5478 2018-08-31 17:46
浏览 394
已采纳

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

Given two arrays or slices for eg:

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

The slices may not be sorted and order doesn't matter.

What is the most efficient way to compute values such that you end up with the common elements of both slices, and the remainder of elements present in one but not the other i.e for the two arrays given above the return values would be:

common := []int{3, 4, 5}
inAButNotB := []int{1, 2}
inBButNotA := []int{6, 7, 8, 9}

Its easy to compute the intersection converting one slice into a map and then iterating over the one to see if values exist. Is there a way to compute the other two values within the same loop?

  • 写回答

1条回答

  • doumanshan6314 2018-08-31 18:09
    关注

    O(len(a) + len(b)) is efficient. For example,

    package main
    
    import (
        "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)
    }
    

    Playground: https://play.golang.org/p/RvGaC9Wfjiv

    Output:

    [1 2 3 4 5]
    [3 4 5 6 7 8 9]
    [3 4 5]
    [1 2]
    [8 6 7 9]
    

    The Go Programming Language Specification

    &    bitwise AND            integers
    |    bitwise OR             integers
    ^    bitwise XOR            integers
    &^   bit clear (AND NOT)    integers
    
    <<   left shift             integer << unsigned integer
    >>   right shift            integer >> unsigned integer
    

    We have 8 bits for uint8. Bit 0 (1 << 0, 1 shift left 0) is a and bit 1 (1 << 1; 1 shift left 1) is b. For uint8 bits, 00000001 is a, 00000010 is b, 00000011 is a and b, and 00000000 is nether a nor b. The | operator sets a bit, the & operator reads a bit.


    The Go Programming Language Specification

    Map types

    A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type.

    The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice. If the key type is an interface type, these comparison operators must be defined for the dynamic key values; failure will cause a run-time panic.

    The algorithm works for any slice type whose elements can be a map key. The comparison operators == and != must be fully defined for operands of the key type.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)