Set, Map & Bit-Vector Discrete Mathematics and Its Applications Baojian Hua
Set
Set Interface signature type set // set type type t // element type set newSet (); int setSize (set s); void setInsert (set s, t x); set setUnion (set s1, set s2); … end
Interface in C #ifndef SET_H #define SET_H typedef struct setStruct *set; // type set typedef void *poly; // type t set newSet (); int setSize (set s); void setInsert (set s, poly x); set setUnion (set s1, set s2); … #endif
Implementation in C // file “set.c” #include “set.h” struct setStruct { // your favorite concrete representation }; set newSet () { // real code goes here } …
Sample Impl ’ Using Linked List #include “linkedList.h” #include “set.h” struct setStruct { linkedList list; };
Sample Impl ’ Using Linked List // functions set newSet () { set s = (set)malloc (sizeof (*s)); s->list = newLinkedList (); return s; } list s
Sample Impl ’ Using Linked List int setSize (set s) { linkList l = s->list; return linkedListSize (l); } list s
Sample Impl ’ Using Linked List void setInsert (set s, poly x) { if (setExists (s, x)) return; linkedListInsert (s->list, x); return; }
Sample Impl ’ Using Linked List int setExists (set s, poly x) { return linkedListExists (s->list, x); }
Equality Testing // How to perform equality testing on // “polymorphic” data? Many solutions: // #1: “equals” function pointer as argument. int linkedListExists (linkedList list, poly x, tyEq equals); // #2: “equals” function pointers in data. int linkedListExist (linkedList list, poly x) { foreach (node p in list) (p->data)->equals (p->data, x); } // As we can see next in C++ or Java.
Client Code int main () { set s1 = newSet (); set s2 = newSet (); for (…) setInsert (s1, …); for (…) setInsert (s2, …); set s3 = setUnion (s1, s2); setOutput (s3); }
Summary So Far set
Set in Java
Interface in Java public interface SetInter // the type “set” { int size (); // “Object” is very polymorphic… void insert (Object x); void union (SetInter s); … } // Follow this, all the stuffs are essentially // same with those in C
Or Using Generic // Type “set”, with type argument “X” public interface SetInter { int size (); void insert (X x); void union (SetInter s); … } // We’ll discuss this strategy in following // slides
Implementation in Java public class Set implements SetInter { // any concrete internal representation public Set () { // code goes here } public int size () { // code goes here } … }
Sample Impl ’ Using Linked List import ….linkedList; public class Set implements SetInter { private linkedList list; public Set () { this.list = new LinkedList (); }
Sample Impl ’ Using Linked List import ….linkedList; public class Set implements SetInter { private linkedList list; public int size () { return this.list.size (); }
Sample Impl ’ Using Linked List import ….linkedList; public class Set implements SetInter { private linkedList list; public void insert (X x) { if (exists (x)) // equality testing? return; this.list.insert (x); return; }
Client Code import ….Set; public class Main { public static void main (string[] args) { SetInter s1 = new Set (); SetInter s2 = new Set (); s1.size (); s1.union (s2); }
Bit-Vector
Bit-Vector Interface interface type bitArray bitArray newBitArray (int size); void assignOne (bitArray ba, int index); bitArray and (bitArray ba1, bitArray ba2); … end
Interface in C #ifndef BIT_ARRAY_H #define BIT_ARRAY_H typedef struct bitArrayStruct *bitArray; bitArray newBitArray (int size); void assignOne (bitArray ba, int index); bitArray and (bitArray ba1, bitArray ba2); … #endif
Implementation in C #include “bitArray.h” // a not-so efficient one struct bitArrayStruct { int *array; int size; }; // What’s this set? size-1 array size a
Operations bitArray newBitArray (int s) { bitArray ba = malloc (sizeof (*ba)); ba->array = malloc (sizeof (*(ba->array)) * s); for (int k=0; k<s; k++) (ba->array)[k] = 0; ba->size = s; return ba; } ??????? 0 s-1 array size ba
Operations bitArray newBitArray (int s) { bitArray ba = malloc (sizeof (*ba)); ba->array = malloc (sizeof (*(ba->array)) * s); for (int k=0; k<s; k++) (ba->array)[k] = 0; ba->size = s; return ba; } s-1 array size ba
Operations bitArray and (bitArray ba1, bitArray ba2) { if (ba1->size != ba2->size) error (…); bitArray ba = newBitArray (); for (…) …; return ba; }
Bit-Array in Java
In Java // I omit the interface for simplicity public class BitArray { private int[] array; public BitArray (int size) { this.array = new int[size]; }
Other Methods public class BitArray { private int[] array; BitArray and (BitArray ba2) { if (this.size () != ba2.size ()) throw new Error (…); BitArray ba = new BitArray (this.size()); … return ba; }
Map
Map Interface signature type map type key type value map newMap (); void mapInsert (map m, key k, value v); value mapLookup (map m, key k); void mapDelete (map m, key k); … end
Interface in C #ifndef MAP_H #define MAP_H typedef struct mapStruct *map; // type map typedef void *key; // type key typedef void *value // type value map newMap (); void mapInsert (map m, key k, value v); poly mapLookup (map m, key k); void mapDelete (map m, key k); … #endif
Implementation in C #include “map.h” struct mapStruct { // your favorite concrete representation }; map newMap () { // real code goes here } // other functions
Sample Impl ’ Using Linked List #include “linkedList.h” #include “map.h” struct mapStruct { linkedList list; };
Sample Impl ’ Using Linked List map newMap () { map m = (map)malloc (sizeof (*m)); m->list = newLinkedList (); return m; } list m
Sample Impl ’ Using Linked List void mapInsert (map m, key k, value v) { linkedList list = m->list; linkedListInsert (list, newTuple (k, v)); return; } list m data next data next data next … k1v1k2v2k3v3
Sample Impl ’ Using Linked List value mapLookup (map m, key k) { linkedList list = m->list; while(…) { // walk through the list and lookup key k // return corresponding v, if found } return NULL; } list m
Bit-Vector-based Set Representation
Big Picture Universe set
Client Code int main () { // cook a universe set set universe = newSet (); // cook sets s1 and s2 set s1 = newSet (); set s2 = newSet (); setUnion (universe, s1, s2); }
What does the Universe Look Like? // Universe is a set of (element, index) tuple. // For instance: Universe = {(“a”, 0), (“b”, 3), (“c”, 1”), (“d”, 2)} // Question: How to build such kind of universe // from the input set elements? // Answer: associate every set element e a unique // (and continuous) integer i (what’s the use?). // Details leave to you.
Big Picture 1. Build the bit-array from the universe {( “ a ”, 0), ( “ b ”, 3), ( “ c ”, 1 ” ), ( “ d ”, 2)} {“a”}{“a”}{“d”}{“d”}
Big Picture 1. Build the bit-array from the universe baSet1 = [0, 0, 0, 0] baSet2 = [0, 0, 0, 0] {( “ a ”, 0), ( “ b ”, 3), ( “ c ”, 1 ” ), ( “ d ”, 2)} {“a”}{“a”}{“d”}{“d”}
Big Picture 1. Build the bit-array from the universe baSet1 = [0, 0, 0, 0] baSet2 = [0, 0, 0, 0] 2. Build bit-array from set baSet1 = [1, 0, 0, 0] baSet2 = [0, 0, 1, 0] {( “ a ”, 0), ( “ b ”, 3), ( “ c ”, 1 ” ), ( “ d ”, 2)} {“a”}{“a”}{“d”}{“d”}
Big Picture 1. Build the bit-array from the universe baSet1 = [0, 0, 0, 0] baSet2 = [0, 0, 0, 0] 2. Build bit-array from set baSet1 = [1, 0, 0, 0] baSet2 = [0, 0, 1, 0] {( “ a ”, 0), ( “ b ”, 3), ( “ c ”, 1 ” ), ( “ d ”, 2)} {“a”}{“a”}{“d”}{“d”} 3. Bit-vector operations baSet3 = or (baSet1, baSet2) baSet3 = [1, 0, 1, 0] 4. Turn baSet3 to ordinary set How? Leave it to you.
How to Store the Universe? // Method 1: stored in a separate set int main () { // cook a universe set set universe = newSet (); // cook two sets s1 and s2 set s1 = newSet (); set s2 = newSet (); setUnion (universe, s1, s2); // ugly }
How to Store the Universe? // Method 2: shared Universe set
How to Make Things Shared? Same ideas, but different mechanisms in different languages: C: external variables C++, Java or C#: static fields What ’ s the pros and cons?
External Variables set universe; void newUniverse () { universe = …; }
Static Fields class Set { static set universe; …; public Set () {…} public setUnion (Set s) {…} }
Client Code int main () { // cook a universe set set universe = newUniverse (); // cook two sets s1 and s2 set s1 = newSet (); set s2 = newSet (); setUnion (s1, s2); // hummm, no universe AT ALL! }