-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathA6.cpp
310 lines (266 loc) · 8.47 KB
/
A6.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/**
* @brief: A6.cpp.
*
* @paragraph: Code Description - This code is used to implement hash table.
*
* @paragraph: Problem Statement - Pick 20 words of various lengths, maximum length 8 and minimum length 3. The words will be of letters a-zA-Z and the space character. Insert them into a hash table. You can use a library for only the hash function. The collision resolution scheme should be open addressing - quadratic. Initially the table size is 31. The program should increase the table size and rehash at load factor of 0.5, it should automatically determine when the load factor goes above 0.5. So, after you inserted about 15 or 16 words, your program automatically doubles the table size and re-inserts (automatically) the old words and then continue the insert of additional words. You do not have to insert the words manually (one by one) but you can add the words in a file and let your program read from the file. At the end print the total number of collisions you get. Submit your code and print screen of your execution.
*
* @author: Shreyans Patel (SSP210009)
*/
#include<iostream>
#include<string.h>
//Necessary Defines
#define NUM_WORDS 20 //Number of words in the list
#define NUM_CHARACTERS 27 //Alphabets and space
#define MAX_LEN 8 //Maximum length of a word
//This hardcoded list represents the words to be inserted into the hash table. Change the defines NUM_WORDS and MAX_LEN according to the changes you make in this list
const char* mWordsArr[NUM_WORDS] = {
"Shreyans",
"The",
"Universe",
"Texas",
"Dallas",
"And",
"Cartoon",
"Apology",
"Discuss",
"Coat",
"Sample",
"Fin Tech",
"Pillow",
"Treaty",
"Rank",
"Choke",
"Camera",
"Receipt",
"Tissue",
"Sheet",
};
//Global Variables
char** mDataTable = NULL;
bool* mVacancyArr = NULL;
int mTableSize = 0;
int mCollisions = 0;
int mTotalCollisions = 0;
/**
* @brief: initializeTable.
* @details: Used to initialize the hash table and dependent list of vacant indexes with given size.
* @param: iSize - Size to allocate.
* @return none.
*/
void initializeTable(int iSize)
{
if(mVacancyArr != NULL)
{
delete mVacancyArr;
mVacancyArr = NULL;
}
if(mDataTable != NULL)
{
for(int tIterator = 0; tIterator < mTableSize; tIterator++)
{
if(mDataTable[tIterator] != NULL)
{
delete mDataTable[tIterator];
mDataTable[tIterator] = NULL;
}
}
delete mDataTable;
mDataTable = NULL;
}
mTableSize = iSize;
mVacancyArr = new bool[iSize];
if(mVacancyArr == NULL)
{
std::cout<<"Memory Allocation Failed"<<std::endl;
return;
}
for(int tIterator = 0; tIterator < mTableSize; tIterator++)
{
mVacancyArr[tIterator] = false;
}
mDataTable = new char*[iSize];
if(mDataTable == NULL)
{
std::cout<<"Memory Allocation Failed"<<std::endl;
return;
}
for(int tIterator = 0; tIterator < mTableSize; tIterator++)
{
mDataTable[tIterator] = new char[MAX_LEN];
if(mDataTable[tIterator] == NULL)
{
std::cout<<"Memory Allocation Failed"<<std::endl;
return;
}
}
std::cout<<"Table Size is: "<<mTableSize<<std::endl;
}
/**
* @brief: hashFunction.
* @details: Used to get an insertion index by converting a string into a unique key.
* @param: iString - String to convert into a key.
* @return int - Insertion index.
*/
int hashFunction(const char* iString)
{
std::string tString = iString;
int tHashCode = 0;
for(int tIterator = 0; tIterator < tString.length(); tIterator++)
{
tHashCode = NUM_CHARACTERS * tHashCode + tString[tIterator];
}
tHashCode %= mTableSize;
if(tHashCode < 0)
{
tHashCode += mTableSize;
}
return tHashCode;
}
/**
* @brief: calculateLoad.
* @details: Used to get the load factor of the table according to the number of inserted keys.
* @param: iNumOfKeys - Number of keys in the table.
* @return float - The load factor.
*/
float calculateLoad(int iNumOfKeys)
{
return ((float)iNumOfKeys / (float)mTableSize);
}
/**
* @brief: isPrimeCheck.
* @details: Check if the number is prime.
* @param: iNumber - Number for checking.
* @return bool - True: Prime, False: Not Prime.
*/
bool isPrimeCheck(int iNumber)
{
if((iNumber == 2) || (iNumber == 3))
{
return true;
}
if((iNumber == 1) || (iNumber % 2 == 0))
{
return false;
}
for(int tIterator = 3; tIterator * tIterator <= iNumber; tIterator += 2)
{
if (iNumber % tIterator == 0)
{
return false;
}
}
return true;
}
/**
* @brief: findNextPrime.
* @details: Find the next prime number greater than or equal to the given number.
* @param: iNumber - Number for checking.
* @return int - Next prime number greater than or equal to the given number.
*/
int findNextPrime(int iNumber)
{
if(iNumber <= 0)
{
iNumber == 3;
}
if(iNumber % 2 == 0)
{
iNumber++;
}
for(; false == isPrimeCheck(iNumber); iNumber += 2);
{
return iNumber;
}
}
/**
* @brief: insertIntoHashTable.
* @details: Insert the given string into the hash table.
* @param: iString - String to insert.
* @return none.
*/
void insertIntoHashTable(const char* iString)
{
int tInsertIndex = hashFunction(iString);
int tTempInsertIndex = tInsertIndex;
int tMultiplier = 1;
while(true == mVacancyArr[tTempInsertIndex])
{
std::cout<<"<<< Collision detected for '"<<iString<<"' at index "<<tTempInsertIndex<<" >>>"<<std::endl;
mCollisions++;
mTotalCollisions++;
tTempInsertIndex = (tInsertIndex + (tMultiplier*tMultiplier)) % mTableSize;
tMultiplier++;
}
std::cout<<"Inserting '"<<iString<<"' at index "<<tTempInsertIndex<<std::endl;
strcpy(mDataTable[tTempInsertIndex], iString);
mVacancyArr[tTempInsertIndex] = true;
}
/**
* @brief: performInsertion.
* @details: Used to insert the given word list into the hash table one at a time.
* @return none.
*/
void performInsertion(void)
{
std::cout<<std::endl<<"Starting Insertion: "<<std::endl;
bool tInsertionDone = false;
int tCount = 0;
while(false == tInsertionDone)
{
for(int tIterator = 0; tIterator < NUM_WORDS; tIterator++)
{
insertIntoHashTable(mWordsArr[tIterator]);
tCount++;
if(0.5 <= calculateLoad(tCount))
{
std::cout<<std::endl<<"Load factor is >= 0.5, initializing resize process..."<<std::endl<<std::endl;
tInsertionDone = false;
break;
}
tInsertionDone = true;
}
if(false == tInsertionDone)
{
tCount = 0;
mCollisions = 0;
int tNewSize = mTableSize * 2;
std::cout<<"New table size is: "<<tNewSize<<std::endl;
tNewSize = findNextPrime(tNewSize);
std::cout<<"We use the prime greater than or equal to the required size. Hence, new size is: "<<tNewSize<<std::endl;
initializeTable(tNewSize);
std::cout<<std::endl<<"Starting Re-insertion: "<<std::endl;
}
else
{
std::cout<<std::endl<<"Insertion Successful"<<std::endl;
std::cout<<std::endl<<"Total collisions (Only Final Table): "<<mCollisions<<std::endl;
std::cout<<"Total collisions (Since Beginning): "<<mTotalCollisions<<std::endl;
}
}
}
/**
* @brief: main.
* @details: Main Function.
* @return int.
*/
int main(void)
{
//Print list of words to insert
std::cout<<"List of words to insert: ";
for(int tIterator = 0; tIterator < NUM_WORDS; tIterator++)
{
if(tIterator == (NUM_WORDS-1))
{
std::cout<<mWordsArr[tIterator];
break;
}
std::cout<<mWordsArr[tIterator]<<",";
}
std::cout<<std::endl<<std::endl;
//Initialize the table with size 31 as given in the problem statement
initializeTable(31);
//Perform insertion of words into the table
performInsertion();
return 0;
}