/* * add (S, x): * Adds the element x to a set S, if it is not present already. * No return value. */ static void add(ref SetList S, int x) { /* if the element is already in the list, * or if it is equal or less than zero, * it will not be added to the list */ if (is_element_of(x, S) || x <= 0) { return; } /* Creates a new node * and fills it with value x */ SetNode add = new SetNode(); add.data = x; /* If the list is empty, * add it as first node in the list */ if (is_empty(S)) { S.first = add; } /* If the list isn't empty, * Iterate through list until the end * and add the new node */ else { SetNode node = S.first; while (node.next != null) { node = node.next; } node.next = add; } }
/* * capacity( S ): * returns the maximum number of values that S can hold. */ static int capacity(SetList S) { /* As a dynamic data structure a LinkedList doesn't have any hard limit on the capacity * It's limited to the current size of the structure, with a maximum potential capacity * defined by the pool of available memory. * The maximum potential capacity could be calculated by filling a list until a * System.OutOfMemoryException is thrown, and counting the number of values added. */ return size(S); }
/* * symmetric_difference ( S, T ): * returns the "symmetric difference" of S and T, * i.e., the union of difference(S, T) and difference(T, S) */ static SetList symmetricDifference(SetList s, SetList t) { return union(difference(s, t), difference(t, s)); }
/* * size( S ): * returns the number of elements in S */ static int size(SetList S) { /* Start counter at 0 */ int size = 0; SetNode node = S.first; /* Iterate through each value in set * increasing counter by 1 each time */ while (node != null) { size++; node = node.next; } /* Return final counter */ return size; }
/* * remove(S, x): * this function removes the element x from the set S. * No return value. */ static void remove(ref SetList s, int x) { SetNode node = s.first; /* Check the very first node * If it contains the value to remove then * replace the current first node with the one afterwards */ if (node.data == x) s.first = node.next; else /* Otherwise iterate through all values in set * until end of set */ { while (node.next != null) { /* Unless the next node contains the value to remove */ if (node.next.data == x) { /* In which case, set the next node to the one * afterwards, removing the next node */ node.next = node.next.next; /* and end the function, job done */ return; } /* Next iteration */ node = node.next; } } }
/* Print_subset * Copy of standard print(), just without newlines when writing to console. * Pretty much just here to make printing powersets prettier. */ static void print_subset(SetList S) { if (is_empty(S)) { Console.Write("{ }"); return; } SetNode node = S.first; System.Console.Write("{ "); while (node != null) { System.Console.Write(node.data + ", "); node = node.next; } System.Console.Write("}"); }
/* * print( S ): * prints a list of the elements of S in order added */ static void print(SetList S) { /* If set is empty, then print default set {} * and end function */ if (is_empty(S)) { Console.WriteLine("{ }"); return; } /* Otherwise iterate through values * and output each one in turn */ SetNode node = S.first; System.Console.Write("{ "); while (node != null) { System.Console.Write(node.data + ", "); node = node.next; } System.Console.WriteLine("}"); }
/* * copy_set ( S ): * Instantiates a new SetList instance with the same values as S. * Returns the new instance. */ static SetList copy_set(SetList S) { SetList newList = new SetList(); newList = S; return newList; }
static void Main() { //variable declaration SetList S = new SetList(); Console.Write("Set S: "); print(S); Console.WriteLine(); //checks whether the list is empty (should be "true") System.Console.WriteLine("is_empty(S): " + is_empty(S)); Console.WriteLine(); add(ref S, 1); add(ref S, 2); add(ref S, 3); add(ref S, 4); add(ref S, 5); add(ref S, 6); add(ref S, 7); add(ref S, 19); System.Console.Write("After adding " + size(S) + " values to set S: "); print(S); Console.WriteLine(); System.Console.WriteLine("Size of S: " + size(S)); Console.WriteLine(); System.Console.WriteLine("is_empty(S): " + is_empty(S)); Console.WriteLine(); SetList T = new SetList(); add(ref T, 1); add(ref T, 2); add(ref T, 4); add(ref T, 5); add(ref T, 8); System.Console.Write("Set T: "); print(T); Console.WriteLine(); System.Console.WriteLine("Size of T: " + size(T)); Console.WriteLine(); Console.WriteLine("Is 3 in set T? " + is_element_of(3, T)); Console.WriteLine(); Console.Write("Set S after removing some elements:"); remove(ref S, 1); remove(ref S, 4); remove(ref S, 6); print(S); Console.WriteLine(); Console.WriteLine("Is 7 in set S? " + is_element_of(7, S)); Console.WriteLine(); Console.WriteLine("X = copy_set(S). Set X:"); SetList X = copy_set(S); print(X); Console.WriteLine(); Console.WriteLine("Is S a subset of T? " + is_subset(S, T)); Console.WriteLine(); Console.WriteLine("union(S, T): "); print(union(S, T)); Console.WriteLine("intersection(S, T): "); print(intersection(S, T)); Console.WriteLine("difference(S, T): "); print(difference(S, T)); Console.WriteLine("difference(T, S): "); print(difference(T, S)); Console.WriteLine("symmetricDifference(S, T): "); print(symmetricDifference(S, T)); SetList Y = new SetList(); PowersetList test = new PowersetList(); Console.Write("Powerset({}): "); PowersetList PS = new PowersetList(); PS = PowerSet(Y); print(PS); add(ref Y, 1); add(ref Y, 2); add(ref Y, 3); add(ref Y, 4); add(ref Y, 5); add(ref Y, 6); Console.Write("Powerset({1,2,3,4,5,6}): "); print(PowerSet(Y)); Console.ReadLine(); }
/* * is_subset( S, T): * tests whether the set S is a subset of set T. * Returns a Boolean value, accordingly. */ static Boolean is_subset(SetList S, SetList T) { //Start at first node SetNode node = S.first; //Iterate through all values of S while (node.next != null) { //If a value of S isn't in T, then not a subset if (!is_element_of(node.data, T)) //so return false return false; //Continue to next node node = node.next; } //If loop completes without returning false, //All values of S are in T, therefore //S is a subset return true; }
/* * is_empty( S ): * checks whether the set S is empty; * returns the Boolean value true or false, accordingly. */ static Boolean is_empty(SetList S) { /* Checks if the list has an initial value */ return (S.first == null); }
/* * is_element_of ( x, S ): * checks whether the value x is in the set S; * returns true or false, accordingly. */ static Boolean is_element_of(int x, SetList S) { /* Iterate through all values */ SetNode node = S.first; while (node != null) /* If value is equal to search, then return true */ if (node.data == x) return true; /* Otherwise continue iterating */ else node = node.next; /* If all values are searched, without finding the value * then value isn't in set, so return false */ return false; }
/* * intersection( S, T): * returns the intersection of sets S and T. */ static SetList intersection(SetList S, SetList T) { SetNode node = S.first; SetList intersection = new SetList(); /* Iterate through all values in set */ while (node != null) { /* If value is in both sets, * then add to intersection set */ if (is_element_of(node.data, T)) { add(ref intersection, node.data); } node = node.next; } /* Return final intersection set */ return intersection; }
/* * difference( S, T ): * returns the "difference" of sets S and T, all values in S that are not in T. */ static SetList difference(SetList S, SetList T) { SetNode node = S.first; SetList diff = new SetList(); /* Iterate through all values in set */ while (node != null) { /* If element is in S but not T * then add it to the differences set. */ if (!is_element_of(node.data, T)) { add(ref diff, node.data); } node = node.next; } /* Return final set of differences */ return diff; }
/* * union( S, T ): * returns the "union" of sets S and T */ static SetList union(SetList S, SetList T) { SetNode node_s = new SetNode(); node_s = S.first; SetNode node_t = new SetNode(); node_t = T.first; /* New SetList container for resulting set */ SetList union = new SetList(); /* adds elements of set S to the union set */ while (node_s != null) { /* Potential duplicates are already handled by the add() procedure */ add(ref union, node_s.data); /* Go to next iteration */ node_s = node_s.next; } /* Add all elements from set T to union set */ while (node_t != null) { add(ref union, node_t.data); node_t = node_t.next; } /* Return the final list */ return union; }
/* Actual powerset generation function * Returns a PowersetList object containing each possible subset * possible to generate from the given set */ static PowersetList PowerSet(SetList S) { /* How many values do we have in original set? * This will affect length of powerset * We create an array with this length to hold values from the set * which simplifies our algorithm later */ int len = size(S); int[] vals = new int[len]; int counter = 0; SetNode node = S.first; /* Iterate through values in set, * adding each to the array */ while (node != null) { vals[counter++] = node.data; node = node.next; } /* At this point, vals[] contains all our set values. * We set up our list container class, and our first node. * Even if there are no values in given set, we still want the empty set {} * so we set that as our first subset. */ PowersetList powerset = new PowersetList(); PowersetNode prev_node = new PowersetNode(); prev_node.data = new SetList(); powerset.first = prev_node; /* Calculate power-set length using 2^N where N = number of values. * Math.Pow isn't C-Core so we created a simple power function for this */ int n = pow(2, len); /* Our empty set {} is at location 0, so we start the loop at 1 * then loop through until we have n values. */ for (int x = 1; x < n; x++) { /* Set up this sub-set's containers */ PowersetNode New_Node = new PowersetNode(); New_Node.data = new SetList(); /* Now iterate through each value in our vals[] array */ for (int i = 0; i < len; i++) { /* If it should be in this subset, then we add it to the current subset. * This is done by using the bitwise operators & and << to check if * the binary conversion of x AND 1 << i is greater than 0. */ if ((x & (1 << i)) > 0) { add(ref New_Node.data, vals[i]); } } /* Finally, add our completed subset to the previous node's next */ prev_node.next = New_Node; prev_node = prev_node.next; } return powerset; }
/* * Task 1 Functions - Basic Set functions * Implemented using a simple LinkedList data structure */ /* * clear_set ( S ): * removes all elements from the set; * returns nothing */ static void clear_set(ref SetList S) { /* Sets the initial node of a list to empty */ S.first = null; }