書いてて飽きてきてしまったのでこれが最速かどうかは分かりませんが、ベンチマークコードも載せておきます。
go
1package common
2
3import (
4 "reflect"
5 "sort"
6 "testing"
7)
8
9func makeCommon(lhs, rhs []int) []int {
10 // 出現回数
11 m := map[int]int{}
12
13 // 存在しない時だけ1にする
14 // LHS で2回発生しても1
15 for _, v := range lhs {
16 if _, ok := m[v]; !ok {
17 m[v] = 1
18 }
19 }
20
21 // 存在する時だけ2にする
22 for _, v := range rhs {
23 if _, ok := m[v]; ok {
24 m[v] = 2
25 }
26 }
27 ret := []int{}
28 for i := range m {
29 if m[i] > 1 {
30 ret = append(ret, i)
31 }
32 }
33 sort.Ints(ret)
34 return ret
35}
36
37func TestMakeCommon(t *testing.T) {
38 tests := []struct {
39 lhs []int
40 rhs []int
41 want []int
42 }{
43 {lhs: []int{1, 2, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
44 {lhs: []int{1, 2, 2, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
45 {lhs: []int{1, 2, 3, 3, 4, 5}, rhs: []int{3, 5}, want: []int{3, 5}},
46 {lhs: []int{1, 1, 1}, rhs: []int{1, 1}, want: []int{1}},
47 {lhs: []int{1, 2, 4, 5}, rhs: []int{3, 5}, want: []int{5}},
48 {lhs: []int{1, 2, 4}, rhs: []int{3, 5}, want: []int{}},
49 {lhs: []int{}, rhs: []int{3, 5}, want: []int{}},
50 {lhs: []int{1, 2}, rhs: []int{}, want: []int{}},
51 {lhs: []int{}, rhs: []int{}, want: []int{}},
52 }
53
54 for _, tt := range tests {
55 got := makeCommon(tt.lhs, tt.rhs)
56 if !reflect.DeepEqual(got, tt.want) {
57 t.Fatalf("want %v but got %v", tt.want, got)
58 }
59 }
60}
61
62func BenchmarkMakeCommon(b *testing.B) {
63 lhs := make([]int, b.N)
64 rhs := make([]int, b.N/2)
65 for i := 0; i < b.N; i++ {
66 lhs[i] = i * 2
67 }
68 for i := 0; i < b.N/2; i++ {
69 rhs[i] = i * 3
70 }
71 b.ResetTimer()
72 makeCommon(lhs, rhs)
73}
common_test.go などに保存して
shell
1$ go test -bench .
2goos: windows
3goarch: amd64
4BenchmarkMakeCommon-4 5000000 396 ns/op
5PASS
6ok _/C_/dev/go-sandbox/dup 2.482s
で実行して下さい。