bag.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // CookieJar - A contestant's algorithm toolbox
  2. // Copyright (c) 2013 Peter Szilagyi. All rights reserved.
  3. //
  4. // CookieJar is dual licensed: use of this source code is governed by a BSD
  5. // license that can be found in the LICENSE file. Alternatively, the CookieJar
  6. // toolbox may be used in accordance with the terms and conditions contained
  7. // in a signed written agreement between you and the author(s).
  8. // Package bag implements a multi-set data structure supporting arbitrary types
  9. // (even a mixture).
  10. //
  11. // Internally it uses a simple map assigning counts to the different values
  12. // present in the bag.
  13. package bag
  14. // Bag data structure (multiset).
  15. type Bag struct {
  16. size int
  17. data map[interface{}]int
  18. }
  19. // Creates a new empty bag.
  20. func New() *Bag {
  21. return &Bag{0, make(map[interface{}]int)}
  22. }
  23. // Inserts an element into the bag.
  24. func (b *Bag) Insert(val interface{}) {
  25. b.data[val]++
  26. b.size++
  27. }
  28. // Removes an element from the bag. If none was present, nothing is done.
  29. func (b *Bag) Remove(val interface{}) {
  30. old, ok := b.data[val]
  31. if ok {
  32. if old > 1 {
  33. b.data[val] = old - 1
  34. } else {
  35. delete(b.data, val)
  36. }
  37. b.size--
  38. }
  39. }
  40. // Returns the total number of elemens in the bag.
  41. func (b *Bag) Size() int {
  42. return b.size
  43. }
  44. // Counts the number of occurances of an element in the bag.
  45. func (b *Bag) Count(val interface{}) int {
  46. return b.data[val]
  47. }
  48. // Executes a function for every element in the bag.
  49. func (b *Bag) Do(f func(interface{})) {
  50. for val, cnt := range b.data {
  51. for ; cnt > 0; cnt-- {
  52. f(val)
  53. }
  54. }
  55. }
  56. // Clears the contents of a bag.
  57. func (b *Bag) Reset() {
  58. *b = *New()
  59. }