Complete Implementation of Sets
Let's look at the complete code implementation of programs on sets.
Complete implementation of set
In this lesson, we’ve added the complete code that we’ve covered so far on different problems on sets (both with and without functions).
Without functions
The complete code in a single code editor is given below. Skim through this and see how complex the implementation of all these tasks would have been to follow if we had not used functions.
#include <iostream>#include<fstream>using namespace std;int main(){const int capacity = 500;int A[capacity] = { 0 }, B[capacity] = { 0 }, sizeA, sizeB;int input, repeatedElement = false;ifstream rdr("Sets.txt");cout << "Size of Set A = ";rdr >> sizeA; cout << sizeA<<"\n";cout << "Size of Set B = ";rdr >> sizeB; cout << sizeB<<"\n";for (int i = 0; i <= sizeA-1; i++){rdr >> input;for (int ei = 0; ei < i-1; ei++){if (input == A[i]){repeatedElement = true;cout << "\nMust have identical elements in the set!!!\n";cout << "Remaining Elements: ";i--;}}if (repeatedElement == false)A[i] = input;repeatedElement =false;}cout << endl;for (int i = 0; i <= sizeB-1; i++){rdr >> input;for (int ei = 0; ei < i; ei++){if (input == B[i]){repeatedElement = true;cout << "\nMust have identical elements in the set!!!\n";cout << "Remaining Elements: ";i--;}}if (repeatedElement == false)B[i] = input;repeatedElement = false;}//Tast 2 - Sorting the two sets//Sorting Afor (int t = 1; t <= sizeA - 1; t++){for (int ai = 0; ai + 1 < sizeA; ai++){if(A[ai]>A[ai+1])swap(A[ai], A[ai + 1]);}}//Sorting Bfor (int t = 1; t <= sizeB - 1; t++){for (int bi = 0; bi + 1 < sizeB; bi++){if(B[bi]>B[bi+1])swap(B[bi], B[bi + 1]);}}//Task 3 - Displaying the two setscout << "A = {";for (int ai = 0; ai <= sizeA - 1; ai++){cout << A[ai];if (ai != sizeA - 1)cout << ", ";}cout << "}" << endl;cout << "B = {";for (int bi = 0; bi <= sizeB -1; bi++){cout << B[bi];if(bi != sizeB -1)cout << ", ";}cout << "}";//Task 4 A is a Subset of B or B is a subset of A or none.int count =0;if (sizeA <= sizeB){for (int ai = 0; ai <= sizeA - 1; ai++){for (int bi = 0; bi <= sizeB - 1; bi++){if (A[ai] == B[bi]) // A[ai] is in B{count++; // remember that A[ai] is presentbreak; // no need to check for this number any further}}}if (count == sizeA)cout << "\nA is a subset of B.\n";elsecout << "\nNeither is a subset of other.\n";}else if (sizeA > sizeB){for (int bi = 0; bi <= sizeB - 1; bi++){for (int ai = 0; ai <= sizeA - 1; ai++){if (B[bi] == A[ai])count++;}}if (count == sizeB)cout << "\nB is a subset of A.\n";elsecout << "\n Neither is a subset of other.\n";}//Task 5int UnionSet[500] = { 0 };for (int ai = 0; ai <= sizeA - 1; ai++){UnionSet[ai] = A[ai]; // Add all the elements in A in the unionSet}int check = 0, ui = sizeA;for (int bi = 0; bi <= sizeB - 1; bi++){check = 0;for (int ai = 0; ai <= sizeA - 1; ai++){if (B[bi] == A[ai])check++;}if (check == 0){UnionSet[ui] = B[bi];ui++;}}int uSize = ui;//Sorting Union-Setfor (int t = 1; t <= uSize-1; t++){for (int ui = 0; ui +1< uSize; ui++){if (UnionSet[ui] > UnionSet[ui + 1])swap(UnionSet[ui], UnionSet[ui + 1]);}}cout << "\nA U B = {";for (int ui = 0; ui <= uSize-1; ui++){cout << UnionSet[ui];if (ui != uSize-1)cout << ", ";}cout << "}";//Task6int intersectionSet[500] = { 0 };int ii = 0;for (int bi = 0; bi <= sizeB - 1; bi++){for (int ai = 0; ai <= sizeA - 1; ai++){if (B[bi] == A[ai])check++;}if (check != 0){intersectionSet[ii] = B[bi];ii++;}check = 0;}//Displaying Intersection Setint iSize = ii;cout << "\nA ^ B = {";for (int i = 0; i <= iSize-1; i++){cout << intersectionSet[i];if (i != iSize-1)cout << ", ";}cout << "}";//Task 7int AMinusB[500];bool found;int mi = 0;for (int ai = 0; ai <= sizeA - 1; ai++){found = false;for (int bi = 0; bi <= sizeB - 1; bi++){if (A[ai] == B[bi]){found = true; break;}}if (!found){AMinusB[mi] = A[ai];mi++;}}int minusSize = mi;cout << "\nA - B: = {";for (int mi = 0; mi <= minusSize - 1; mi++){cout << AMinusB[mi];if (mi != minusSize - 1)cout << ", ";}cout << "}";{int BMinusA[500];mi = 0;bool present;for (int bi = 0; bi <= sizeB - 1; bi++){present = false;for (int ai = 0; ai <= sizeA - 1; ai++){if (B[bi] == A[ai]){present=true;break;}}if (!present){BMinusA[mi] = B[bi];mi++;}}cout << "\nB - A: = {";for (int i = 0; i <= mi-1; i++){cout << BMinusA[i];if (i != mi-1)cout << ", ";}cout << "}";}//Task 8cout << "\nA x B: = {\n";for (int ai = 0; ai <= sizeA-1; ai++){cout << "\t\t\t";for (int bi = 0; bi <= sizeB - 1; bi++){cout << "(" << A[ai] << ", " << B[bi] << ")";if (bi != (sizeB - 1) || ai != (sizeA - 1))cout << ", ";}cout << endl;}cout << "\n\t\t}";return 0;}
Problems with the above implementation
Congratulations! You have successfully implemented the different programs regarding sets with the help of several nested loops. In programs, where we did not make functions, you must have noticed the following problems:
- We were repeating some of the tasks with different data, e.g., printing the arrays, sorting the arrays, searching in arrays, computing the set difference of the two sets, and so on. This repetition must be avoided. We overcome this issue when we implement the same using functions.
- This repetition always wastes a lot of time as one needs to make the entire effort again with a similar problem with different inputs.
- It is challenging to extend this type of code because it becomes unmanageable due to its huge length.
- It can be hard to debug if there is a logical error somewhere in the code.
With functions
Let’s look at the complete code. You may see how all the repetition of the code in the above playground is completely avoided through modularisation.
#include <iostream>#include<fstream>using namespace std;void loadSet(const char Msg[], int S[ ], int &size, ifstream &rdr){rdr >> size;cout << "The size of the set "<<Msg<<" : "<<size<<endl;int input, repeatedElement = false;for (int i = 0; i <= size-1; i++){rdr >> input;for (int ei = 0; ei < i; ei++){if (input == S[i]){repeatedElement = true;cout << "\nMust have identical elements in the set!!!\n";cout << "Remaining Elements: ";i--;}}if (repeatedElement == false)S[i] = input;repeatedElement =false;}}void sort(int S[ ], int size){for (int t = 1; t <= size - 1; t++){for (int si = 0; si + 1 < size; si++){if(S[si]>S[si+1])swap(S[si], S[si + 1]);}}}void setPrint(const char Msg[ ],int S[ ], int size){cout << Msg<<" = {";for (int si = 0; si <= size - 1; si++){cout << S[si];if (si != size - 1)cout << ", ";}cout << "}" << endl;}bool isPresent(int S[ ], int size, int t){for(int si=0; si<size; si++){if(S[si]==t)return true;}return false;}bool isSubset(int A1[ ], int sizeA1,int A2[ ], int sizeA2){int count = 0;for (int ai = 0; ai <= sizeA1 - 1; ai++){if(!isPresent(A2, sizeA2, A1[ai]))return false;// remember that A1[ai] is present}return true;}void UNION(int A[ ], int sizeA, int B[ ],int sizeB, int UnionSet[ ], int &sizeU){for (int ai=0; ai<=sizeA-1; ai++){UnionSet[ai] = A[ai];// Add all the elements in unionSet}int check = 0, ui = sizeA;for (int bi=0; bi<= sizeB-1; bi++){if(!isPresent(UnionSet,ui,B[bi])){// if B[bi] is not in UnionSetUnionSet[ui] = B[bi];ui++;}}sizeU = ui;//Sorting Union-Setsort(UnionSet, sizeU);}void subsetTest(int A[ ], int sizeA,int B[ ], int sizeB){int count =0;if (sizeA <= sizeB){ // checking A is subset of Bif(isSubset(A,sizeA,B,sizeB))cout << "\nA is a subset of B.\n";elsecout << "\n Neither is a subset \n";}else if (sizeA > sizeB){ // checking B is subset of Aif(isSubset(B,sizeB,A,sizeA))cout << "\nB is a subset of A.\n";elsecout << "\n Neither is a subset \n";}}void intersection(int A[ ], int sizeA,int B[ ], int sizeB,int IntersectionSet[ ],int& iSize){int ii = 0;int check;for (int bi = 0; bi <= sizeB - 1; bi++){if(isPresent(A, sizeA, B[bi])){IntersectionSet[ii] = B[bi];ii++;}check = 0;}iSize = ii;}void setMinus(int A1[ ], int sizeA1,int A2[ ], int sizeA2,int R[ ], int &sizeR){bool found;int mi = 0;for (int ai = 0; ai <= sizeA1-1; ai++){if(!isPresent(A2, sizeA2, A1[ai])){R[mi] = A1[ai];mi++;}}sizeR = mi;}void crossProduct(const char Msg[],int A1[],int sizeA1,int A2[],int sizeA2){cout << Msg<<": = {\n";for (int ai = 0; ai <= sizeA1-1; ai++){cout << "\t\t\t";for (int bi = 0; bi<=sizeA2-1;bi++){cout<<"("<<A1[ai]<<", "<< A2[bi] << ")";// not printing comma ',' at the endif (bi!=(sizeA2-1)||ai!=(sizeA1-1))cout << ", ";}cout << endl;}cout<<"\t}";}int main(){const int capacity = 500;int A[capacity] = { 0 }, B[capacity] = { 0 }, sizeA, sizeB;ifstream rdr("Sets.txt");loadSet("A",A, sizeA, rdr);loadSet("B",B, sizeB, rdr);// Tast 2 - Sorting the two sets// Sorting A and Bsort(A, sizeA);sort(B, sizeB);//Task 3 - Displaying the two setssetPrint("A", A, sizeA);setPrint("B", B, sizeB);//Task 4 A is a Subset of B or B is a subset of A or none.subsetTest(A, sizeA, B, sizeB);//Task 5int UnionSet[500] = { 0 };int sizeU;UNION(A, sizeA, B, sizeB, UnionSet, sizeU);setPrint("A U B", UnionSet, sizeU);//Task6int IntersectionSet[500] = { 0 };int iSize;intersection(A, sizeA, B, sizeB, IntersectionSet, iSize);setPrint("A ^ B", IntersectionSet, iSize);//Task 7int AMinusB[500];int minusSize;setMinus(A, sizeA, B, sizeB, AMinusB, minusSize);setPrint("A-B", AMinusB, minusSize);int BMinusA[500];setMinus(B, sizeB, A, sizeA, BMinusA, minusSize);setPrint("B-A", BMinusA, minusSize);//Task 8crossProduct("AxB",A, sizeA, B, sizeB);return 0;}
Pros of using functions
From the 2nd implementation, we have the following very important points,
- Modularized code looks much cleaner.
- It is much more manageable.
- Functional implementation has significantly reduced redundancies in the code.
- While coding such a huge program, errors arising are a natural occurrence. If the code is in modularized/functional form, it is much more easily debugged.
- Modularized code is considered a great precious programming skill. Without it, you cannot work with other programmers because your code will not be usable by others.