From d4a3f1c93c2ea7098024af39b52cd3925aef1cfe Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 27 Mar 2019 14:34:24 -0300 Subject: [PATCH] Added set operations and example --- examples/set_ops.c | 88 +++++++++++++++++++++++++++++++++++++++++ src/treeset.h | 99 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 examples/set_ops.c diff --git a/examples/set_ops.c b/examples/set_ops.c new file mode 100644 index 0000000..95dc5fc --- /dev/null +++ b/examples/set_ops.c @@ -0,0 +1,88 @@ +#include +#include +#include "../src/macro_collections.h" + +// change to hashset to have the same effects +COLLECTION_GENERATE(TREESET, PUBLIC, set, set, , , int) + +void print_set(set *s) +{ + size_t index; + int result; + set_iter iter; + set_iter_new(&iter, s); + for (set_iter_tostart(&iter); !set_iter_end(&iter);) + { + set_iter_next(&iter, &result, &index); + if (index == 0) + printf("[ %2d, ", result); + else if (index == s->count - 1) + printf("%2d ]\n", result); + else + printf("%2d, ", result); + } +} + +int intcmp(int a, int b) +{ + return a - b; +} + +int main(int argc, char const *argv[]) +{ + set *set1 = set_new(intcmp); + set *set2 = set_new(intcmp); + + for (int i = 1; i <= 20; i++) + set_insert(set1, i); + + for (int i = 11; i <= 30; i++) + set_insert(set2, i); + + set *set3 = set_union(set1, set2); + + print_set(set1); + printf("UNION\n"); + print_set(set2); + printf("=\n"); + print_set(set3); + + printf("\n\n"); + + set *set4 = set_intersection(set1, set2); + + print_set(set1); + printf("INTERSECTION\n"); + print_set(set2); + printf("=\n"); + print_set(set4); + + printf("\n\n"); + + set *set5 = set_difference(set1, set2); + + print_set(set1); + printf("DIFFERENCE\n"); + print_set(set2); + printf("=\n"); + print_set(set5); + + printf("\n\n"); + + set *set6 = set_symmetric_difference(set1, set2); + + print_set(set1); + printf("SYMMETRIC DIFFERENCE\n"); + print_set(set2); + printf("=\n"); + print_set(set6); + + set_free(set1); + set_free(set2); + set_free(set3); + set_free(set4); + set_free(set5); + set_free(set6); + + return 0; +} diff --git a/src/treeset.h b/src/treeset.h index 13ec2f4..57fd3c8 100644 --- a/src/treeset.h +++ b/src/treeset.h @@ -558,10 +558,101 @@ } \ } \ \ - FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \ - FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \ - FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \ - FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \ + FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \ + { \ + SNAME##_iter iter1, iter2; \ + size_t index; \ + V var; \ + \ + SNAME *_set_r_ = PFX##_new(_set1_->cmp); \ + \ + PFX##_iter_new(&iter1, _set1_); \ + PFX##_iter_new(&iter2, _set2_); \ + \ + for (PFX##_iter_tostart(&iter1); !PFX##_iter_end(&iter1);) \ + { \ + PFX##_iter_next(&iter1, &var, &index); \ + PFX##_insert(_set_r_, var); \ + } \ + \ + for (PFX##_iter_tostart(&iter2); !PFX##_iter_end(&iter2);) \ + { \ + PFX##_iter_next(&iter2, &var, &index); \ + PFX##_insert(_set_r_, var); \ + } \ + \ + return _set_r_; \ + } \ + \ + FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \ + { \ + SNAME##_iter iter; \ + size_t index; \ + V var; \ + \ + SNAME *_set_r_ = PFX##_new(_set1_->cmp); \ + SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \ + SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \ + \ + PFX##_iter_new(&iter, _set_A_); \ + \ + for (PFX##_iter_tostart(&iter); !PFX##_iter_end(&iter);) \ + { \ + PFX##_iter_next(&iter, &var, &index); \ + if (PFX##_get_node(_set_B_, var) != NULL) \ + PFX##_insert(_set_r_, var); \ + } \ + \ + return _set_r_; \ + } \ + \ + FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \ + { \ + SNAME##_iter iter; \ + size_t index; \ + V var; \ + \ + SNAME *_set_r_ = PFX##_new(_set1_->cmp); \ + \ + PFX##_iter_new(&iter, _set1_); \ + \ + for (PFX##_iter_tostart(&iter); !PFX##_iter_end(&iter);) \ + { \ + PFX##_iter_next(&iter, &var, &index); \ + if (PFX##_get_node(_set2_, var) == NULL) \ + PFX##_insert(_set_r_, var); \ + } \ + \ + return _set_r_; \ + } \ + \ + FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \ + { \ + SNAME##_iter iter1, iter2; \ + size_t index; \ + V var; \ + \ + SNAME *_set_r_ = PFX##_new(_set1_->cmp); \ + \ + PFX##_iter_new(&iter1, _set1_); \ + PFX##_iter_new(&iter2, _set2_); \ + \ + for (PFX##_iter_tostart(&iter1); !PFX##_iter_end(&iter1);) \ + { \ + PFX##_iter_next(&iter1, &var, &index); \ + if (PFX##_get_node(_set2_, var) == NULL) \ + PFX##_insert(_set_r_, var); \ + } \ + \ + for (PFX##_iter_tostart(&iter2); !PFX##_iter_end(&iter2);) \ + { \ + PFX##_iter_next(&iter2, &var, &index); \ + if (PFX##_get_node(_set1_, var) == NULL) \ + PFX##_insert(_set_r_, var); \ + } \ + \ + return _set_r_; \ + } \ \ FMOD void PFX##_iter_new(SNAME##_iter *iter, SNAME *target) \ { \