TEST(Test02, EqualityTests) { { for (int i = 0; i < NUM_TESTS; i++) { Set s; Set t; createEmptySet(&s); randomSet(&s); createCopySet(&t, &s); ASSERT_TRUE(isEqualToSet(&t, &s)); ASSERT_TRUE(isEqualToSet(&s, &t)); insertSet(&t, MAX_SET_SIZE); ASSERT_FALSE(isEqualToSet(&s, &t)); ASSERT_FALSE(isEqualToSet(&t, &s)); randomSet(&t); ASSERT_FALSE(isEqualToSet(&t, &s)); destroySet(&s); destroySet(&t); } } }
TEST(Test03, RelationalTests) { { Set s; Set t; createEmptySet(&s); createEmptySet(&t); for (int i = 0; i < NUM_TESTS; i++) { randomSet(&s); reassignSet(&t, &s); ASSERT_TRUE(isSubsetOf(&s, &t)); ASSERT_TRUE(isSubsetOf(&t, &s)); ASSERT_TRUE(isEqualToSet(&s, &t)); ASSERT_TRUE(isEqualToSet(&t, &s)); insertSet(&s, rand() % MAX_SET_SIZE + MAX_SET_SIZE); ASSERT_TRUE(isSubsetOf(&t, &s)); ASSERT_FALSE(isSubsetOf(&s, &t)); } destroySet(&s); destroySet(&t); } }
/** * Remove all elements from 'self' that are not also elements of 'other.' * If 'self' is empty or identical to 'other' or if 'other' is empty, do nothing. * Update the length of 'self.' * * param self: set to store intersection of 'self' and 'other' in. * param other: set to check against 'self' for any matching members. * return: N/A */ void intersectFromSet(Set* self, const Set* other) { if ((isEqualToSet(self, other)) || (self->len == 0) || (!isSorted(self))) { return; } if (other->len == 0) { /* the intersection of any set with an empty set is an empty set */ self->len = 0; return; } int selfIndex = 0; int otherIndex = 0; int intersectIndex = 0; while (selfIndex < self->len && otherIndex < other->len) { if (self->elements[selfIndex] == other->elements[otherIndex]) { self->elements[intersectIndex] = self->elements[selfIndex]; /* should only add a member if present in both sets */ intersectIndex++; selfIndex++; otherIndex++; } else if (self->elements[selfIndex] > other->elements[otherIndex]) { /* member may be in set but at different index, or not in both sets. Don't add. */ otherIndex++; } else if (self->elements[selfIndex] < other->elements[otherIndex]) { /* member may be in set but at different index, or not in both sets. Don't add. */ selfIndex++; } } self->len = intersectIndex; /* update new length of self */ }
/** * Returns true if every element of 'self' is in 'other.' * False otherwise. Since sets are subsets of themselves, * return true if 'self' and 'other' are identical sets. * Increments a counter 'selfInOther' for every member found * in both sets. If 'selfInOther' is equal to the length of * 'self' after the loop is terminated, every member in 'self' * has been found in 'other' signifying 'self' as a subset of other. * * param self: 1st set. Checked to see if every member here is in 'other.' * param other: 2nd set. If all members of 'self' are found in this set, * 'self' is a subset of this. * return : true if 'self' is a subset of 'other.' False otherwise. */ bool isSubsetOf(const Set* self, const Set* other) { if (isEqualToSet(self, other)) { /* a set is always subset of itself */ return true; } int selfIndex = 0; int selfInOther = 0; int otherIndex = 0; while (selfIndex < self->len && otherIndex < other->len) { if (self->elements[selfIndex] < other->elements[otherIndex]) { return false; } else if (self->elements[selfIndex] > other->elements[otherIndex]) { otherIndex++; } else if (self->elements[selfIndex] == other->elements[otherIndex]) { selfIndex++; otherIndex++; selfInOther++; } } return self->len == selfInOther; }
void checkCase(setFun fun, Set* s1, Set* s2, Set* expect) { Set res; createCopySet(&res, s1); (*fun)(&res, s2); assert(isEqualToSet(&res, expect)); destroySet(&res); }
bool checkCaseNew(setFun fun, Set *s1, Set *s2, Set *expect) { Set res; createCopySet(&res, s1); (*fun)(&res, s2); bool test_result = isEqualToSet(&res, expect); destroySet(&res); return test_result; }
void equalityTests(void) { int i; for (i = 0; i < number_of_tests; i += 1) { Set s; Set t; createEmptySet(&s); randomSet(&s); createCopySet(&t, &s); assert(isEqualToSet(&t, &s)); assert(isEqualToSet(&s, &t)); insertSet(&t, maximum_set_size); assert(! isEqualToSet(&s, &t)); assert(! isEqualToSet(&t, &s)); randomSet(&t); assert(! isEqualToSet(&t, &s)); destroySet(&s); destroySet(&t); } // This test could fail with small probability printf("The equality tests have been passed\n"); }
void relationalTests() { Set s; Set t; int i; createEmptySet(&s); createEmptySet(&t); for (i = 0; i < number_of_tests; i += 1) { randomSet(&s); assignSet(&t, &s); assert(isSubsetOf(&s, &t)); assert(isSubsetOf(&t, &s)); assert(isEqualToSet(&s, &t)); assert(isEqualToSet(&t, &s)); insertSet(&s, rand() % maximum_set_size + maximum_set_size); assert(isSubsetOf(&t, &s)); assert(! isSubsetOf(&s, &t)); } printf("The relational tests have been passed\n"); destroySet(&s); destroySet(&t); }
/* add all elements of other to self (obviously, without creating duplicate elements) */ void unionInSet(Set* self, const Set* other) { if (isEmptySet(other)) { return; } //adding nothing to self set if (isEqualToSet (self, other)) { return; } //same set, nothing to add if (isSubsetOf (other, self)) { return; } //everything in other already in self if (self == other) { return; } //same set, nothing to add if (self->len == 0) { createCopySet (self, other); } else { Set copy_set; createCopySet (©_set, self); copy_set.capacity = copy_set.len + other->len; destroySet (self); self->elements = (int*) malloc (copy_set.capacity * sizeof (int)); //self now has room to union two unique sets int copy_index = 0; int other_index = 0; int self_index = 0; while (copy_index < copy_set.len || other_index < other->len) { if (copy_set.elements[copy_index] == other->elements[other_index]) { self->elements[self_index] = copy_set.elements[copy_index]; other_index += 1; copy_index += 1; } else if ((other_index >= other->len || copy_set.elements[copy_index] < other->elements[other_index]) && copy_index < copy_set.len) { self->elements[self_index] = copy_set.elements[copy_index]; copy_index += 1; } else if ((copy_index >= copy_set.len || copy_set.elements[copy_index] > other->elements[other_index]) && other_index < other->len) { self->elements[self_index] = other->elements[other_index]; other_index += 1; } self_index += 1; } self->len = self_index; self->capacity = copy_set.capacity; destroySet (©_set); } //might have to recreate insert code/subset code here /*code here*/ //have two sets (one a copy of self), depending on which number is lower of the two sets at their respective indicies, put that one first into self //assert (checkValidSet (self)); //test code, remove later }
/* remove all elements from self that are not also elements of other */ void intersectFromSet(Set* self, const Set* other) { int* temp = (int*)malloc(sizeof(int) * self->len); //create a temp arr int* tempAddress = temp; //copy of the temp for later reference //if both sets are eql just return if (isEqualToSet(self, other)) { free(temp); //free up temp return; } //if the second set is empty just return an empty set if (isEmptySet(other)) { free(self->elements); //freeup old set self->elements = temp; //temp is an empty set self->len = 0; //empty set return; } //if the first set is empty then return itself if (isEmptySet(self)) { free(temp); //freeup temp return; } int i = 0, j = 0, newLen = 0; //two indeces for both sets //search throguh the sets until we reached the end of either of the sets while (i != self->len && j != other->len){ if (self->elements[i] < other->elements[j]) { ++i; //if ith el of self is less then move to the next el } else { if (other->elements[j] < self->elements[i]) { ++j; //if jth el of other is less then move to the next el } else { *temp = self->elements[i]; // if both elements are eql then it gonna be added to the intersection set (i.e. temp) ++temp; //increment temp ++newLen; //increment the length of the intersection set ++i; //increment conters ++j; } } } free(self->elements); //free up old set self->elements = tempAddress; //update the address of intersection set tempAddress = temp = 0; //destroy the pointer self->len = newLen; //update the length of intersection set }
/* return true if every element of self is also an element of other */ bool isSubsetOf(const Set* self, const Set* other) { if (isEmptySet(self)) { return true; // if empty is subset to any set } if (isEqualToSet(self, other)) { return true; //if both eql then they're subset of one another } if (isEmptySet(other)) { return false; // if other is empty then self cannot be its subset (we know that self is noth empty) } if (self->len > other->len) { return false; //self cannot be a subset if it has more elements than other } if (self->len == other->len) { //if the lengths are eql but they are not eql sets, return false return false; } int i = 0, j = 0; while (i != self->len && j != other->len) { //if the elements of curr indeces are eql the increment both indeces if (self->elements[i] == other->elements[j]) { i++; j++; } else { //if element of self is bigger than element of other then increment only the other index if (self->elements[i] > other->elements[j]) { j++; } //if element of other is bigger than elemnt of self then self is not a subset of other else { return false; } } } //if the index of self is not eql to its size then its noself-<t a subset if (i != self->len) { return false; } //finished the loop? hurray it's a subset return true; }
/** * Remove all elements from self that are also elements of other. * If either set is empty, do nothing. If the sets are identical, * set the length of 'self' do 0 indicating an empty set. If the * length of self (before the subtraction) does not equal the index * used to traverse through the set (selfIndex) contained in 'self,' there are * members that are unique to 'self' that have not been correctly * stored into 'self.' The second loop taken conditionally if the length * of 'self' does not equal 'selfIndex' correctly solves this. Finally, * update the new length of 'self.' * * param self: set to store the subtraction of 'self' and 'other' in. * param other: set to compare to 'self' for the subtraction of sets operation. * return: N/A */ void subtractFromSet(Set* self, const Set* other) { if ((self->len == 0) || (other->len == 0) || (!isSorted(self))) { return; } if (isEqualToSet(self, other)) { self->len = 0; return; } int selfIndex = 0; int otherIndex = 0; int subIndex = 0; while (selfIndex < self->len && otherIndex < other->len) { /* O(N). Find subtraction members of 'self.' */ if (self->elements[selfIndex] < other->elements[otherIndex]) { /* current index of 'self' member is unique to self. Keep it in the array */ self->elements[subIndex] = self->elements[selfIndex]; subIndex++; selfIndex++; } else if (self->elements[selfIndex] > other->elements[otherIndex]) { otherIndex++; /* 'other' has a unique member in its set. However, we only care about changing the set 'self.' */ } else if (self->elements[selfIndex] == other->elements[otherIndex]) { selfIndex++; /* don't include shared members in a subtraction set */ otherIndex++; } } if (self->len != selfIndex) { /* there are unique members in self unaccounted for */ for (int index = selfIndex; index < self->len; index++) { self->elements[subIndex] = self->elements[index]; subIndex++; /* used as counter to assign as length of self */ } } self->len = subIndex; /* update new length of 'self.' */ }
/* remove all elements from self that are not also elements of other */ void intersectFromSet(Set* self, const Set* other) { if (isEmptySet(self)) { return; } //can't remove anything from empty set if (isEqualToSet (self, other)) { return; } //all elements aready in common if (isSubsetOf (self, other)) { return; } //everything in self is in other, nothing to remove if (self == other) { return; } //all elements already in common /*code here*/ //have two sets (one a copy of self), if they don't match increase other index until they do, if they match add to self and increase both indicies //might have to recreate remove code/subset code here Set copy_set; createCopySet (©_set, self); copy_set.capacity = copy_set.len; destroySet (self); self->elements = (int*) malloc (copy_set.capacity * sizeof (int)); //copy original set into copy_set and rebuild self int copy_index = 0; int other_index = 0; int self_index = 0; while (copy_index < copy_set.len && other_index < other->len) { if (copy_set.elements[copy_index] < other->elements[other_index]) { copy_index += 1; } else if (copy_set.elements[copy_index] > other->elements[other_index]) { other_index += 1; } else if (copy_set.elements[copy_index] == other->elements[other_index]) { self->elements[self_index] = copy_set.elements[copy_index]; self_index += 1; copy_index += 1; other_index += 1; } } self->len = self_index; self->capacity = copy_set.capacity; destroySet (©_set); //assert (checkValidSet (self)); //test code, remove later }
void isEqualTimeFun(void) { bogus_value = isEqualToSet(setA, setAPrime); }
void algebraicTests(void) { Set empty; Set universal; int i; Set s; Set t; Set u; Set v; Set w; createEmptySet(&empty); createEmptySet(&universal); for (i = 0; i < maximum_set_size; i += 1) { insertSet(&universal, i); } createEmptySet(&s); createEmptySet(&t); createEmptySet(&u); createEmptySet(&v); createEmptySet(&w); for (i = 0; i < number_of_tests; i += 1) { randomSet(&u); randomSet(&v); randomSet(&w); /* u + v == v + u */ assignSet(&s, &u); unionInSet(&s, &v); assignSet(&t, &v); unionInSet(&t, &u); assert(isEqualToSet(&s, &t)); /* u + (v + w) == (u + v) + w */ assignSet(&t, &v); unionInSet(&t, &w); assignSet(&s, &u); unionInSet(&s, &t); assignSet(&t, &u); unionInSet(&t, &v); unionInSet(&t, &w); assert(isEqualToSet(&s, &t)); /* u * v == v * u */ assignSet(&s, &u); intersectFromSet(&s, &v); assignSet(&t, &v); intersectFromSet(&t, &u); assert(isEqualToSet(&s, &t)); /* u * (v * w) == (u * v) * w */ assignSet(&t, &v); intersectFromSet(&t, &w); assignSet(&s, &u); intersectFromSet(&s, &t); assignSet(&t, &u); intersectFromSet(&t, &v); intersectFromSet(&t, &w); assert(isEqualToSet(&s, &t)); /* u - v == u - (u * v) */ assignSet(&s, &u); intersectFromSet(&s, &v); assignSet(&t, &u); subtractFromSet(&t, &s); assignSet(&s, &u); subtractFromSet(&s, &v); assert(isEqualToSet(&s, &t)); /* additional tests, not implemented assert(w * (u - v) == w * u - w * v); assert(u * (v + w) == (u * v) + (u * w)); assert(universal - (u * v) == (universal - u) + (universal - v)); assert(universal - (u + v) == (universal - u) * (universal - v)); */ } printf("The algebraic tests have been passed\n"); destroySet(&empty); destroySet(&universal); destroySet(&s); destroySet(&t); destroySet(&u); destroySet(&v); destroySet(&w); }
TEST(Test07, AlgebraicTests) { { Set empty; Set universal; Set r; Set s; Set t; Set u; Set v; Set w; int i; createEmptySet(&empty); createEmptySet(&universal); for (i = 0; i < MAX_SET_SIZE; i++) { insertSet(&universal, i); } createEmptySet(&r); createEmptySet(&s); createEmptySet(&t); createEmptySet(&u); createEmptySet(&v); createEmptySet(&w); ASSERT_FALSE(isEqualToSet(&empty, &universal)); for (i = 0; i < NUM_TESTS; i++) { randomSet(&u); randomSet(&v); randomSet(&w); /* w * (u - v) == w * u - w * v */ assignSet(&s, &u); subtractFromSet(&s, &v); assignSet(&r, &w); intersectFromSet(&r, &s); assignSet(&t, &w); intersectFromSet(&t, &v); assignSet(&s, &w); intersectFromSet(&s, &u); subtractFromSet(&s, &t); ASSERT_TRUE(isEqualToSet(&r, &s)); /* u * (v + w) == (u * v) + (u * w) */ assignSet(&s, &v); unionInSet(&s, &w); assignSet(&r, &u); intersectFromSet(&r, &s); assignSet(&t, &u); intersectFromSet(&t, &w); assignSet(&s, &u); intersectFromSet(&s, &v); unionInSet(&s, &t); ASSERT_TRUE(isEqualToSet(&r, &s)); /* universal - (u * v) == (universal - u) + (universal - v) */ assignSet(&s, &u); intersectFromSet(&s, &v); assignSet(&r, &universal); subtractFromSet(&r, &s); assignSet(&t, &universal); subtractFromSet(&t, &v); assignSet(&s, &universal); subtractFromSet(&s, &u); unionInSet(&s, &t); ASSERT_TRUE(isEqualToSet(&r, &s)); /* universal - (u + v) == (universal - u) * (universal - v) */ assignSet(&s, &u); unionInSet(&s, &v); assignSet(&r, &universal); subtractFromSet(&r, &s); assignSet(&t, &universal); subtractFromSet(&t, &v); assignSet(&s, &universal); subtractFromSet(&s, &u); intersectFromSet(&s, &t); ASSERT_TRUE(isEqualToSet(&r, &s)); } destroySet(&empty); destroySet(&universal); destroySet(&r); destroySet(&s); destroySet(&t); destroySet(&u); destroySet(&v); destroySet(&w); } }