#include #include /* The hash table used to contain at position i, the string whose hash value is i, and we hoped there would only be one. Now at that position it contains all the strings whose hash value is i. So it is now an array of linked lists, and we can get meaningful information on how frequent clashes are. */ struct Link { string word; Link * next; Link(string s, Link * n = NULL) { word = s; next = n; } }; struct LinkedList { Link * head; LinkedList() { head = NULL; } bool search(string s) { Link * p = head; while (p != NULL) { if (p->word == s) return true; p = p->next; } return false; } void insert(string s) { head = new Link(s, head); } int length() { int count = 0; Link * p = head; while (p != NULL) { count += 1; p = p->next; } return count; } }; const int size = 10000; int hash(string s) { int h = 8192; const int len = s.length(); for (int i = 0; i < len; i += 1) h = h * 64 + s[i]; if (h < 0) h = -h; return h % size; } string cleanup(string s) { string r = ""; for (int i = 0; i < s.length(); i += 1) { char c = s[i]; if (isalpha(c)) r += (char)tolower(c); } return r; } void main() { LinkedList words[size]; while (true) { string s; cin >> s; if (cin.fail()) break; s = cleanup(s); if (s == "") continue; const int h = hash(s); if (words[h].search(s)) { } else words[h].insert(s); } int counts[20]; for (int i = 0; i < 20; i += 1) counts[i] = 0; for (int i = 0; i < size; i += 1) counts[words[i].length()] += 1; for (int i = 0; i < 20; i += 1) cout << "linked list length " << i << " appeared " << counts[i] << " times\n"; cout << "\n"; }