mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
datatypes: Set
implementation (#14853)
This commit is contained in:
parent
b08f500c60
commit
9b9115471f
@ -26,5 +26,5 @@ println(stack)
|
|||||||
- [x] Stack (LIFO)
|
- [x] Stack (LIFO)
|
||||||
- [x] Queue (FIFO)
|
- [x] Queue (FIFO)
|
||||||
- [x] Min heap (priority queue)
|
- [x] Min heap (priority queue)
|
||||||
- [ ] Set
|
- [x] Set
|
||||||
- [ ] ...
|
- [ ] ...
|
||||||
|
130
vlib/datatypes/set.v
Normal file
130
vlib/datatypes/set.v
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
module datatypes
|
||||||
|
|
||||||
|
pub struct Set<T> {
|
||||||
|
mut:
|
||||||
|
elements map[T]u8
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks the element is exists.
|
||||||
|
fn (set Set<T>) exists(element T) bool {
|
||||||
|
return element in set.elements
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds the element to set, if it is not present already.
|
||||||
|
fn (mut set Set<T>) add(element T) {
|
||||||
|
set.elements[element] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes the element from set.
|
||||||
|
fn (mut set Set<T>) remove(element T) {
|
||||||
|
set.elements.delete(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pick returns an arbitrary element of set, if set is not empty.
|
||||||
|
fn (mut set Set<T>) pick() ?T {
|
||||||
|
for k, _ in set.elements {
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
return error('Set is empty.')
|
||||||
|
}
|
||||||
|
|
||||||
|
// rest returns the set consisting of all elements except for the arbitrary element.
|
||||||
|
fn (mut set Set<T>) rest() ?[]T {
|
||||||
|
element := set.pick()?
|
||||||
|
return set.elements.keys().filter(it != element)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pop returns an arbitrary element and deleting it from set.
|
||||||
|
fn (mut set Set<T>) pop() ?T {
|
||||||
|
element := set.pick()?
|
||||||
|
set.elements.delete(element)
|
||||||
|
return element
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete all elements of set.
|
||||||
|
fn (mut set Set<T>) clear() {
|
||||||
|
set.elements = map[T]u8{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks whether the two given sets are equal (i.e. contain all and only the same elements).
|
||||||
|
fn (mut l Set<T>) equal(r Set<T>) bool {
|
||||||
|
if l.elements.len != r.elements.len {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for e, _ in r.elements {
|
||||||
|
if e !in l.elements {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks whether the set is empty.
|
||||||
|
fn (mut set Set<T>) is_empty() bool {
|
||||||
|
return set.size() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// size returns the number of elements in the set.
|
||||||
|
fn (mut set Set<T>) size() int {
|
||||||
|
return set.elements.len
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy returns a copy of all the elements in the set.
|
||||||
|
fn (mut set Set<T>) copy() Set<T> {
|
||||||
|
return Set<T>{
|
||||||
|
elements: set.elements.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add_all adds the whole `elements` array to the set
|
||||||
|
fn (mut set Set<T>) add_all(elements []T) {
|
||||||
|
for element in elements {
|
||||||
|
set.add(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @union returns the union of the two sets.
|
||||||
|
fn (mut l Set<T>) @union(r Set<T>) Set<T> {
|
||||||
|
mut set := l
|
||||||
|
for e, _ in r.elements {
|
||||||
|
set.add(e)
|
||||||
|
}
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
// intersection returns the intersection of sets.
|
||||||
|
fn (mut l Set<T>) intersection(r Set<T>) Set<T> {
|
||||||
|
mut set := l
|
||||||
|
for e, _ in l.elements {
|
||||||
|
if !r.exists(e) {
|
||||||
|
set.remove(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for e, _ in r.elements {
|
||||||
|
if !l.exists(e) {
|
||||||
|
set.remove(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
// difference returns the difference of sets.
|
||||||
|
fn (mut l Set<T>) difference(r Set<T>) Set<T> {
|
||||||
|
mut set := l
|
||||||
|
for e, _ in l.elements {
|
||||||
|
if r.exists(e) {
|
||||||
|
set.remove(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
// subset returns true if the set `r` is a subset of the set `l`.
|
||||||
|
fn (mut l Set<T>) subset(r Set<T>) bool {
|
||||||
|
for e, _ in r.elements {
|
||||||
|
if e !in l.elements {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
117
vlib/datatypes/set_test.v
Normal file
117
vlib/datatypes/set_test.v
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
module datatypes
|
||||||
|
|
||||||
|
fn test_exists() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add('foo')
|
||||||
|
assert set.exists('foo')
|
||||||
|
assert set.exists('bar') == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_remove() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.remove('foo')
|
||||||
|
set.add('foo')
|
||||||
|
assert set.exists('foo')
|
||||||
|
set.remove('foo')
|
||||||
|
assert set.exists('foo') == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_size() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add('foo')
|
||||||
|
set.add('foo')
|
||||||
|
assert set.size() == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_pop() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add('foo')
|
||||||
|
set.pop() or { return }
|
||||||
|
assert set.exists('foo') == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_clear() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add('foo')
|
||||||
|
set.clear()
|
||||||
|
assert set.size() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_rest() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add('foo')
|
||||||
|
set.add('bar')
|
||||||
|
array := set.rest() or { return }
|
||||||
|
assert array.len == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_equal() {
|
||||||
|
mut first_set := Set<string>{}
|
||||||
|
mut second_set := Set<string>{}
|
||||||
|
first_set.add('foo')
|
||||||
|
assert second_set.equal(first_set) == false
|
||||||
|
second_set.add('foo')
|
||||||
|
assert second_set.equal(first_set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_is_empty() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
assert set.is_empty()
|
||||||
|
set.add('foo')
|
||||||
|
assert set.is_empty() == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_union() {
|
||||||
|
mut first_set := Set<string>{}
|
||||||
|
mut second_set := Set<string>{}
|
||||||
|
first_set.add_all(['b', 'c', 'd'])
|
||||||
|
second_set.add_all(['a', 'e'])
|
||||||
|
mut third_set := first_set.@union(second_set)
|
||||||
|
assert third_set.exists('a')
|
||||||
|
assert third_set.exists('b')
|
||||||
|
assert third_set.exists('c')
|
||||||
|
assert third_set.exists('d')
|
||||||
|
assert third_set.exists('e')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_intersection() {
|
||||||
|
mut first_set := Set<string>{}
|
||||||
|
first_set.add_all(['foo', 'bar', 'baz'])
|
||||||
|
mut second_set := Set<string>{}
|
||||||
|
second_set.add_all(['bar', 'baz', 'boo'])
|
||||||
|
mut third_set := first_set.intersection(second_set)
|
||||||
|
assert third_set.exists('foo') == false
|
||||||
|
assert third_set.exists('bar')
|
||||||
|
assert third_set.exists('baz')
|
||||||
|
assert third_set.exists('boo') == false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_difference() {
|
||||||
|
mut first_set := Set<string>{}
|
||||||
|
mut second_set := Set<string>{}
|
||||||
|
first_set.add_all(['foo', 'bar', 'baz'])
|
||||||
|
second_set.add_all(['bar', 'baz', 'boo'])
|
||||||
|
mut third_set := first_set.difference(second_set)
|
||||||
|
assert third_set.exists('foo')
|
||||||
|
assert third_set.exists('bar') == false
|
||||||
|
assert third_set.exists('baz') == false
|
||||||
|
assert third_set.exists('boo') == false
|
||||||
|
first_set.clear()
|
||||||
|
second_set.clear()
|
||||||
|
third_set.clear()
|
||||||
|
first_set.add_all(['bar', 'baz', 'boo'])
|
||||||
|
second_set.add_all(['foo', 'bar', 'baz'])
|
||||||
|
third_set = first_set.difference(second_set)
|
||||||
|
assert third_set.exists('foo') == false
|
||||||
|
assert third_set.exists('bar') == false
|
||||||
|
assert third_set.exists('baz') == false
|
||||||
|
assert third_set.exists('boo')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_subset() {
|
||||||
|
mut set := Set<string>{}
|
||||||
|
set.add_all(['a', 'b', 'c'])
|
||||||
|
mut subset := Set<string>{}
|
||||||
|
subset.add_all(['b', 'c'])
|
||||||
|
assert set.subset(subset)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user