From 419d73a3b60232bc6cdc93834e0767756f0bec0e Mon Sep 17 00:00:00 2001 From: Marcelo Da cruz pinto Date: Wed, 12 Aug 2020 22:42:05 -0700 Subject: [PATCH 1/2] Simple implementation of set intersection --- sets/hashset/hashset.go | 11 +++++++++++ sets/hashset/hashset_test.go | 12 ++++++++++++ sets/linkedhashset/linkedhashset.go | 11 +++++++++++ sets/linkedhashset/linkedhashset_test.go | 12 ++++++++++++ sets/treeset/treeset.go | 11 +++++++++++ sets/treeset/treeset_test.go | 12 ++++++++++++ 6 files changed, 69 insertions(+) diff --git a/sets/hashset/hashset.go b/sets/hashset/hashset.go index 815d049..e49696e 100644 --- a/sets/hashset/hashset.go +++ b/sets/hashset/hashset.go @@ -97,3 +97,14 @@ func (set *Set) String() string { str += strings.Join(items, ", ") return str } + +// Intersection returns the intersection between two sets +func (set *Set) Intersection(another *Set) *Set { + result := New() + for item, _ := range another.items { + if set.Contains(item) { + result.Add(item) + } + } + return result +} diff --git a/sets/hashset/hashset_test.go b/sets/hashset/hashset_test.go index cf63c89..c6f48f1 100644 --- a/sets/hashset/hashset_test.go +++ b/sets/hashset/hashset_test.go @@ -105,6 +105,18 @@ func TestSetSerialization(t *testing.T) { assert() } +func TestSetIntersection(t *testing.T) { + set := New("a", "b", "c", "d") + anotherSet := New("c", "d", "f", "g") + intersection := set.Intersection(anotherSet) + if actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := set.Contains("c", "d"); actualValue != true { + t.Errorf("Got %v expected %v", actualValue, true) + } +} + func benchmarkContains(b *testing.B, set *Set, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/sets/linkedhashset/linkedhashset.go b/sets/linkedhashset/linkedhashset.go index e589a12..df4deb3 100644 --- a/sets/linkedhashset/linkedhashset.go +++ b/sets/linkedhashset/linkedhashset.go @@ -116,3 +116,14 @@ func (set *Set) String() string { str += strings.Join(items, ", ") return str } + +// Intersection returns the intersection between two sets +func (set *Set) Intersection(another *Set) *Set { + result := New() + for item, _ := range another.table { + if set.Contains(item) { + result.Add(item) + } + } + return result +} diff --git a/sets/linkedhashset/linkedhashset_test.go b/sets/linkedhashset/linkedhashset_test.go index 10b6da2..728c5ff 100644 --- a/sets/linkedhashset/linkedhashset_test.go +++ b/sets/linkedhashset/linkedhashset_test.go @@ -358,6 +358,18 @@ func TestSetSerialization(t *testing.T) { assert() } +func TestSetIntersection(t *testing.T) { + set := New("a", "b", "c", "d") + anotherSet := New("c", "d", "f", "g") + intersection := set.Intersection(anotherSet) + if actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := set.Contains("c", "d"); actualValue != true { + t.Errorf("Got %v expected %v", actualValue, true) + } +} + func benchmarkContains(b *testing.B, set *Set, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/sets/treeset/treeset.go b/sets/treeset/treeset.go index 7efbf2d..fd23610 100644 --- a/sets/treeset/treeset.go +++ b/sets/treeset/treeset.go @@ -111,3 +111,14 @@ func (set *Set) String() string { str += strings.Join(items, ", ") return str } + +// Intersection returns the intersection between two sets +func (set *Set) Intersection(another *Set) *Set { + result := NewWith(set.tree.Comparator) + for _, item := range another.Values() { + if set.Contains(item) { + result.Add(item) + } + } + return result +} diff --git a/sets/treeset/treeset_test.go b/sets/treeset/treeset_test.go index b3cfca9..81d1a7a 100644 --- a/sets/treeset/treeset_test.go +++ b/sets/treeset/treeset_test.go @@ -367,6 +367,18 @@ func TestSetSerialization(t *testing.T) { assert() } +func TestSetIntersection(t *testing.T) { + set := NewWithStringComparator("a", "b", "c", "d") + anotherSet := NewWithStringComparator("c", "d", "f", "g") + intersection := set.Intersection(anotherSet) + if actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := set.Contains("c", "d"); actualValue != true { + t.Errorf("Got %v expected %v", actualValue, true) + } +} + func benchmarkContains(b *testing.B, set *Set, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { From 508e436ad1a892e575245ac0d1ed9d088ce29802 Mon Sep 17 00:00:00 2001 From: Marcelo Da cruz pinto Date: Thu, 13 Aug 2020 08:40:32 -0700 Subject: [PATCH 2/2] Adding Intersection function to the Set interface --- sets/sets.go | 1 + 1 file changed, 1 insertion(+) diff --git a/sets/sets.go b/sets/sets.go index 2573297..a81ec14 100644 --- a/sets/sets.go +++ b/sets/sets.go @@ -16,6 +16,7 @@ type Set interface { Add(elements ...interface{}) Remove(elements ...interface{}) Contains(elements ...interface{}) bool + Intersection(another *Set) *Set containers.Container // Empty() bool