libflint/src/lfset.c

125 lines
2.8 KiB
C
Raw Normal View History

#include "lfset.h"
2021-02-01 22:06:37 +00:00
2021-02-01 22:27:01 +00:00
void set_init(Set* set, int (*match)(const void* a, const void* b),
2021-02-01 22:06:37 +00:00
void (*destroy)(void* data)) {
ll_init(set, destroy);
set->match = match;
}
2021-02-01 22:27:01 +00:00
void set_destroy(Set* set) {
2021-02-01 22:06:37 +00:00
ll_destroy(set);
}
2021-02-01 22:27:01 +00:00
int set_insert(Set* set, const void* data) {
2021-02-01 22:06:37 +00:00
if (set_is_member(set, data)) {
return 1;
}
return ll_ins_next(set, set->tail, data);
}
2021-02-01 22:27:01 +00:00
int set_remove(Set* set, void** data) {
ListNode* node = NULL;
2021-02-01 22:06:37 +00:00
for (node = set->head; node != NULL; node = node->next) {
if (set->match(*data, node->data)) {
break;
}
}
if (node == NULL) {
return -1;
}
return ll_remove_next(set, node, data);
}
2021-02-01 22:27:01 +00:00
int set_union(Set* setu, const Set* a, const Set* b) {
ListNode* node;
2021-02-01 22:06:37 +00:00
void* data;
set_init(setu, a->match, NULL);
for (node = a->head; node != NULL; node = node->next) {
data = node->data;
if (ll_ins_next(setu, setu->tail, data) != 0) {
set_destroy(setu);
return -1;
}
}
for (node = b->head; node != NULL; node = node->next) {
if (set_is_member(a, node->data)) {
continue;
}
data = node->data;
if (ll_ins_next(setu, setu->tail, data) != 0) {
set_destroy(setu);
return -1;
}
}
return 0;
}
2021-02-01 22:27:01 +00:00
int set_intersection(Set* seti, const Set* a, const Set* b) {
ListNode* node;
2021-02-01 22:06:37 +00:00
void* data;
set_init(seti, a->match, NULL);
for (node = a->head; node != NULL; node = node->next) {
data = node->data;
if (set_is_member(b, data)) {
if (ll_ins_next(seti, seti->tail, data)) {
set_destroy(seti);
return -1;
}
}
}
return 0;
}
2021-02-01 22:27:01 +00:00
int set_difference(Set* setd, const Set* a, const Set* b) {
ListNode* node;
2021-02-01 22:06:37 +00:00
void* data;
set_init(setd, a->match, NULL);
for (node = a->head; node != NULL; node = node->next) {
data = node->data;
if (!set_is_member(b, data)) {
if (ll_ins_next(setd, setd->tail, data)) {
set_destroy(setd);
return -1;
}
}
}
return 0;
}
2021-02-01 22:27:01 +00:00
int set_is_member(const Set* set, const void* data) {
for (ListNode* node = set->head; node != NULL; node = node->next) {
2021-02-01 22:06:37 +00:00
if (set->match(data, node->data)) {
return 1;
}
}
return 0;
}
2021-02-01 22:27:01 +00:00
int set_is_subset(const Set* a, const Set* b) {
2021-02-01 22:06:37 +00:00
if (a->size > b->size) {
return 0;
}
2021-02-01 22:27:01 +00:00
for (ListNode* node = a->head; node != NULL; node = node->next) {
2021-02-01 22:06:37 +00:00
if (!set_is_member(b, node->data)) {
return 0;
}
}
return 1;
}
2021-02-01 22:27:01 +00:00
int set_is_equal(const Set* a, const Set* b) {
2021-02-01 22:06:37 +00:00
if (a->size == b->size) {
return 0;
}
return set_is_subset(a, b);
}