1
+ #include < iostream>
2
+ #include < cassert>
3
+ #include < fstream>
4
+ #include < string>
5
+ #include < sstream>
6
+ using namespace std ;
7
+
8
+ template <class v >
9
+ struct HashItem
10
+ {
11
+ int key;
12
+ v value;
13
+ short int status;
14
+ };
15
+
16
+ template <class v >
17
+ class HashMap
18
+ {
19
+ protected:
20
+ HashItem<v>* hashArray;
21
+ int capacity;
22
+ int currentElements;
23
+ void doubleCapacity ()
24
+ {
25
+ int oldCapacity = capacity;
26
+ this ->capacity = capacity*2 ;
27
+ HashItem<v>* newHashArray = new HashItem<v> [capacity] ();
28
+
29
+ cout<<endl<<" Doubling the capacity from " <<oldCapacity<<" to " <<this ->capacity <<" and rearranging all the key value pairs.\n " ;
30
+ for (int i=0 ; i<oldCapacity; i++)
31
+ if (hashArray[i].status ==2 )// if occupied
32
+ insert_helper (hashArray[i].key , hashArray[i].value , newHashArray);
33
+
34
+ this ->hashArray =newHashArray;
35
+ newHashArray = nullptr ;
36
+ }
37
+ virtual int getNextCandidateIndex (int key, int i, HashItem<v>* hashArr)
38
+ {
39
+ int index = (key+i)%capacity;
40
+ if (hashArr[index ].status ==0 )// if this next candidate index is free, then send its index number or check for the next one
41
+ return index ;
42
+ return getNextCandidateIndex (key, ++i, hashArr);
43
+ }
44
+ void insert_helper (int const key, v const value, HashItem<v>* arr)
45
+ {
46
+ int index = key%capacity;
47
+
48
+ if (arr[index ].status ==2 )// if occupied
49
+ index = getNextCandidateIndex (key, 1 , arr);
50
+
51
+ arr[index ].key =key;
52
+ arr[index ].value =value;
53
+ arr[index ].status =2 ;// occupied
54
+ cout<<" index: " <<index <<" ,key: " <<key<<" ,value: " <<value<<endl;
55
+ }
56
+ public:
57
+ HashMap ()
58
+ {
59
+ capacity = 7 ;// prime number
60
+ currentElements = 0 ;
61
+ hashArray = new HashItem<v> [capacity] ();
62
+ }
63
+ HashMap (int const _capacity)
64
+ {
65
+ assert (capacity>1 );
66
+ capacity = _capacity;
67
+ currentElements = 0 ;
68
+ hashArray = new HashItem<v> [capacity] ();
69
+ }
70
+ HashItem<v>* getHashArray ()
71
+ {
72
+ return this ->hashArray ;
73
+ }
74
+ void insert (int const key, v const value, HashItem<v>* hashArr)
75
+ {
76
+ if ( ( ((float )(currentElements)) / ((float )(capacity)) ) >= 0.75 )// load factor
77
+ doubleCapacity ();
78
+
79
+ insert_helper (key, value, hashArr);
80
+
81
+ currentElements++;
82
+ }
83
+ bool deleteKey (int const key) const
84
+ {
85
+ for (int i=0 ; i<this ->capacity ; i++)
86
+ if (hashArray[i].key == key)
87
+ {
88
+ hashArray[i].status = 1 ;// key deleted
89
+ cout<<key<<" deleted.\n " ;
90
+ return true ;
91
+ }
92
+
93
+ cout<<" key not found.\n " ;
94
+ return false ;
95
+ }
96
+ v* get (int const key) const
97
+ {
98
+ for (int i=0 ; i<this ->capacity ; i++)
99
+ if (hashArray[i].key == key)
100
+ {
101
+ cout<<" key found at index" <<i<<endl;
102
+ return (&hashArray[i].value );
103
+ }
104
+
105
+ cout<<" key not found.\n " ;
106
+ return nullptr ;
107
+ }
108
+ ~HashMap ()
109
+ {
110
+ if (hashArray!=nullptr )
111
+ hashArray=nullptr ;
112
+ delete hashArray;
113
+ }
114
+ };
115
+
116
+ template <class v >
117
+ class QHashMap : public HashMap <v>
118
+ {
119
+ public:
120
+ int getNextCandidateIndex (int key, int i, HashItem<v>* hashArr)
121
+ {
122
+ // int _key = (key + (i*i));
123
+ // if(_key<0)
124
+ // _key+=this->capacity;
125
+
126
+ int index = (key + (i*i)) % this ->capacity ;
127
+ if (hashArr[index ].status ==0 )// if free
128
+ return index ;
129
+ return getNextCandidateIndex (key, ++i, hashArr);
130
+ }
131
+ };
132
+
133
+ template <class v >
134
+ class DHashMap : public HashMap <v>
135
+ {
136
+ public:
137
+ int getNextCandidateIndex (int key, int i, HashItem<v>* hashArr)
138
+ {
139
+ int first_value = key % this ->capacity ;
140
+ int second_value = 7 - (key % 7 );
141
+ int candidate_index = (first_value + (i*second_value)) % this ->capacity ;
142
+
143
+ if (hashArr[candidate_index].status ==0 )// if free
144
+ return candidate_index;
145
+ return getNextCandidateIndex (key, ++i, hashArr);
146
+ }
147
+ };
148
+
149
+ void populateHash (string filename, HashMap<string> *hash)
150
+ {
151
+ ifstream fin;
152
+ fin.open (filename);
153
+ int Tsize;
154
+ fin>>Tsize;
155
+ fin.ignore ();
156
+
157
+ while (Tsize>0 )
158
+ {
159
+ string name;
160
+ getline (fin, name);
161
+
162
+ int att = name.find (' ' );
163
+ string _key = name.substr (0 , att);
164
+ // int id = stoi(_key, nullptr, 10);
165
+ stringstream id (_key);
166
+ int ID=0 ;
167
+ id>>ID;
168
+
169
+ name=name.substr (att+1 , name.size ());
170
+
171
+ hash->insert (ID, name, hash->getHashArray ());
172
+
173
+ Tsize--;
174
+ }
175
+ }
176
+ int main ()
177
+ {
178
+ cout<<" LINEAR PROBING\n " ;
179
+ HashMap<string> *map=new HashMap<string>;
180
+ populateHash (" students.txt" , map);
181
+ cout<<" Calling get function:\t " <<*map->get (9 )<<endl<<endl;
182
+ cout<<" Calling deleteKey function:\t " ;map->deleteKey (9 );cout<<endl;
183
+ // assert((map->get(9)==nullptr));
184
+ free (map);
185
+
186
+ cout<<" QUADRATIC PROBING\n " ;
187
+ QHashMap<string> *Qmap=new QHashMap<string>;
188
+ populateHash (" students.txt" , Qmap);
189
+ cout<<" Calling get function:\t " <<*Qmap->get (9 )<<endl<<endl;
190
+ cout<<" Calling deleteKey function:\t " ;Qmap->deleteKey (9 );cout<<endl;
191
+ // assert(Qmap->get(9)==nullptr);
192
+ free (Qmap);
193
+
194
+ cout<<" DOUBLE HASHING\n " ;
195
+ DHashMap<string> *Dmap=new DHashMap<string>;
196
+ populateHash (" students.txt" , Dmap);
197
+ cout<<" Calling get function:\t " <<*Dmap->get (9 )<<endl<<endl;
198
+ cout<<" Calling deleteKey function:\t " ;Dmap->deleteKey (9 );cout<<endl;
199
+ // assert(Dmap->get(9)==nullptr);
200
+ free (Dmap);
201
+
202
+ return 0 ;
203
+ }
0 commit comments