Soham_K

HashTable.cpp

Nov 25th, 2020 (edited)
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.83 KB | None | 0 0
  1. #include <iostream>
  2. #include <bits/stdc++.h>
  3. #define NIL -999999999
  4. #define N 10000
  5. #define Chaining 1
  6. #define Double 2
  7. #define Custom 3
  8. using namespace std;
  9.  
  10. class HashTable;
  11. void wordGenerator(string s[], int n)
  12. {
  13.     srand(time(0));
  14.     for(int i=0; i<n; i++)
  15.     {
  16.         for(int j=0; j<7; j++) {
  17.             string c(1, 'a'+rand()%26);
  18.             s[i] += c;
  19.         }
  20.     }
  21. }
  22.  
  23. class HashNode
  24. {
  25.     int val;
  26.     string key;
  27.     HashNode *next;
  28.     friend class HashTable;
  29. public:
  30.     HashNode() {
  31.         val = NIL;
  32.         key = "";
  33.         next = nullptr;
  34.     }
  35.     HashNode(string key, int val) {
  36.         this->key = key;
  37.         this->val = val;
  38.         next = nullptr;
  39.     }
  40. };
  41.  
  42. class HashTable
  43. {
  44.     int len;
  45.     int colres;
  46.     int maxsize;
  47.     int nCol;
  48.     int func;
  49.     int probe;
  50.     int nSearch;
  51.     HashNode **table;
  52.     int hashfuncOne(string key);
  53.     int hashfuncTwo(string key);
  54.     int hashfuncAux(string key);
  55. public:
  56.     HashTable(int func=1, int colres=Chaining) {
  57.         len = 0;
  58.         maxsize = 0;
  59.         this->func = func;
  60.         this->colres = colres;
  61.         nCol = 0;
  62.         probe = 0;
  63.         nSearch = 0;
  64.         table = nullptr;
  65.     }
  66.     HashTable(int n, int func = 1, int colres = Chaining) {
  67.         len = 0;
  68.         nCol = 0;
  69.         maxsize = n;
  70.         probe = 0;
  71.         nSearch = 0;
  72.         table = new HashNode*[maxsize];
  73.         for(int i=0; i<maxsize; i++)
  74.         {
  75.             table[i] = new HashNode();
  76.         }
  77.         this->colres = colres;
  78.         this->func = func;
  79.     }
  80.     void setTableSize(int n) {
  81.         maxsize = n;
  82.         table = new HashNode*[maxsize];
  83.         for(int i=0; i<maxsize; i++)
  84.         {
  85.             table[i] = new HashNode();
  86.         }
  87.     }
  88.     void inSert(string key, int val);
  89.     int seArch(string key);
  90.     void deleteKey(string key);
  91.     void printResult(int cases);
  92. };
  93.  
  94. int HashTable::hashfuncOne(string key)
  95. {
  96.     long long hashind = 31;
  97.     int c;
  98.     for(int i=0; i<key.length();  i++) {
  99.         c = key[i];
  100.         hashind = 67*hashind + c;
  101.     }
  102.     hashind %= maxsize;
  103.     if(hashind<0) {
  104.         hashind += maxsize;
  105.         //cout << "in hash one:" << hashind << endl;
  106.     }
  107.     return hashind;
  108. }
  109.  
  110. int HashTable::hashfuncTwo(string key)
  111. {
  112.     long long hashind = 5381;
  113.     int c, i=0;
  114.     while(i<key.length()) {
  115.         c = key[i];
  116.         hashind = ((hashind << 5) + hashind) + c; /* hash * 33 + c */
  117.         i++;
  118.     }
  119.     return hashind%maxsize;
  120. }
  121.  
  122. int HashTable::hashfuncAux(string key)
  123. {
  124.     long long hashind = 29;
  125.     int c;
  126.     for(int i=0; i<key.length();  i++) {
  127.         c = key[i];
  128.         if(c%2==0)
  129.             hashind = hashind*3 + c;
  130.         else
  131.             hashind = hashind*3 + c*7;
  132.         if(hashind%5==0 && hashind%10!=0)
  133.             hashind += 6;
  134.         else if(hashind%5==0 && hashind%10==0)
  135.             hashind += 1;
  136.         if(hashind%2==0 && hashind%10==8)
  137.             hashind += 3;
  138.         else if(hashind%2==0)
  139.             hashind += 7;
  140.     }
  141.  
  142.     hashind %= maxsize;
  143.     if(hashind<0)
  144.         hashind += maxsize;
  145.     return hashind;
  146. }
  147.  
  148. void HashTable::inSert(string key, int val)
  149. {
  150.     long long hindx;
  151.     int col = 0;
  152.     if(func == 1)
  153.         hindx = hashfuncOne(key);
  154.     else if(func == 2)
  155.         hindx = hashfuncTwo(key);
  156.     else
  157.         return;
  158.  
  159.     if(table[hindx]->key.empty())
  160.     {
  161.         table[hindx]->key = key;
  162.         table[hindx]->val = val;
  163.         len++;
  164.         return;
  165.     }
  166.     else if(colres == Chaining)
  167.     {
  168.         HashNode *node = new HashNode(key, val);
  169.         HashNode *last = table[hindx];
  170.         while(last->next != nullptr) {
  171.             last = last->next;
  172.         }
  173.         last->next = new HashNode();
  174.         last->next = node;
  175.         nCol++;
  176.         return;
  177.     }
  178.  
  179.     if(colres == Double && len<maxsize)
  180.     {
  181.         int i=1;
  182.         //cout << "in here" << endl;
  183.         while(!table[hindx]->key.empty()) {
  184.             if(func == 1)
  185.                 hindx = (hashfuncOne(key) + i*hashfuncAux(key)) % maxsize;
  186.             else if(func == 2)
  187.                 hindx = (hashfuncTwo(key) + i*hashfuncAux(key)) % maxsize;
  188.             if(hindx<0)
  189.                 hindx += maxsize;
  190.             //cout << hindx << " ";
  191.             if(i == maxsize)
  192.                 return;
  193.             i++;
  194.             col++;
  195.         }
  196.         //cout << endl;
  197.         table[hindx]->key = key;
  198.         table[hindx]->val = val;
  199.         nCol += col;
  200.         len++;
  201.     }
  202.     else if(colres == Custom && len<maxsize)
  203.     {
  204.         int c1=13, c2=20;
  205.         int i=1;
  206.         while(!table[hindx]->key.empty()) {
  207.             if(func == 1)
  208.                 hindx = (hashfuncOne(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  209.             else if(func == 2)
  210.                 hindx = (hashfuncTwo(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  211.             if(hindx<0)
  212.                 hindx += maxsize;
  213.             if(i == maxsize)
  214.                 return;
  215.             i++;
  216.             col++;
  217.         }
  218.         table[hindx]->key = key;
  219.         table[hindx]->val = val;
  220.         nCol += col;
  221.         len++;
  222.     }
  223.     else
  224.         cout << "HashTable is full" << endl;
  225. }
  226.  
  227. int HashTable::seArch(string key)
  228. {
  229.     int hindx, p=0;
  230.     if(func == 1)
  231.         hindx = hashfuncOne(key);
  232.     else if(func == 2)
  233.         hindx = hashfuncTwo(key);
  234.     else
  235.         return NIL;
  236.  
  237.     if(table[hindx]->key == key) {
  238.         probe++;
  239.         nSearch++;
  240.         return table[hindx]->val;
  241.     }
  242.     else if(colres == Chaining)
  243.     {
  244.         HashNode *last = table[hindx]->next;
  245.         while(last!=nullptr && last->key != key) {
  246.             p++;
  247.             last = last->next;
  248.             if(last->key == key) {
  249.                 nSearch++;
  250.                 probe += p;
  251.                 return last->val;
  252.             }
  253.         }
  254.         int ans = last->val;
  255.         if(ans!=NIL)    nSearch++;
  256.         return ans;
  257.     }
  258.     else if(colres == Double)
  259.     {
  260.         int i=1;
  261.         while(table[hindx]->key != key) {
  262.             if(func == 1)
  263.                 hindx = (hashfuncOne(key) + i*hashfuncAux(key)) % maxsize;
  264.             else if(func == 2)
  265.                 hindx = (hashfuncTwo(key) + i*hashfuncAux(key)) % maxsize;
  266.  
  267.             if(table[hindx]->key == key) {
  268.                 nSearch++;
  269.                 probe += p;
  270.                 return table[hindx]->val;
  271.             }
  272.             else if(i==maxsize)
  273.                 return NIL;
  274.             i++;
  275.             p++;
  276.         }
  277.         return NIL;
  278.     }
  279.     else if(colres == Custom)
  280.     {
  281.         int c1=13, c2=20;
  282.         int i=1;
  283.         while(table[hindx]->key != key) {
  284.             if(func == 1)
  285.                 hindx = (hashfuncOne(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  286.             else if(func == 2)
  287.                 hindx = (hashfuncTwo(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  288.  
  289.             if(table[hindx]->key == key) {
  290.                 nSearch++;
  291.                 probe += p;
  292.                 return table[hindx]->val;
  293.             }
  294.             else if(i==maxsize)
  295.                 return NIL;
  296.             p++;
  297.             i++;
  298.         }
  299.         return NIL;
  300.     }
  301. }
  302.  
  303. void HashTable::deleteKey(string key)
  304. {
  305.     int hindx;
  306.     if(func == 1)
  307.         hindx = hashfuncOne(key);
  308.     else if(func == 2)
  309.         hindx = hashfuncTwo(key);
  310.     else
  311.         return;
  312.  
  313.     if(table[hindx]->key == key)
  314.     {
  315.         if(colres == Chaining) {
  316.             HashNode *x = table[hindx];
  317.             HashNode *nxt = table[hindx]->next;
  318.             HashNode *nxtnxt = nullptr;
  319.             if(nxt != nullptr)
  320.                 nxtnxt = nxt->next;
  321.             x->key = nxt->key;
  322.             x->val = nxt->val;
  323.             x->next = nxtnxt;
  324.         }
  325.         else if(colres == Double || colres == Custom) {
  326.             table[hindx]->val = NIL;
  327.             table[hindx]->key = "";
  328.         }
  329.     }
  330.     else if(colres == Chaining)
  331.     {
  332.         HashNode *prevx = nullptr;
  333.         HashNode *x = table[hindx];
  334.         while(x->key != key) {
  335.             prevx = x;
  336.             x = x->next;
  337.         }
  338.         if(prevx != nullptr)
  339.             prevx->next = x->next;
  340.     }
  341.     else if(colres == Double)
  342.     {
  343.         int i=1;
  344.         while(table[hindx]->key != key) {
  345.             if(func == 1)
  346.                 hindx = (hashfuncOne(key) + i*hashfuncAux(key)) % maxsize;
  347.             else if(func == 2)
  348.                 hindx = (hashfuncTwo(key) + i*hashfuncAux(key)) % maxsize;
  349.  
  350.             if(i == maxsize)
  351.                 return;
  352.             i++;
  353.         }
  354.         table[hindx]->key = "";
  355.         table[hindx]->val = NIL;
  356.         len--;
  357.     }
  358.     else if(colres == Custom)
  359.     {
  360.         int c1=13, c2=20;
  361.         int i=1;
  362.         while(table[hindx]->key != key) {
  363.             if(func == 1)
  364.                 hindx = (hashfuncOne(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  365.             else if(func == 2)
  366.                 hindx = (hashfuncTwo(key) + c1*i*hashfuncAux(key) + c2*i*i) % maxsize;
  367.  
  368.             if(i==maxsize)
  369.                 return;
  370.             i++;
  371.         }
  372.         table[hindx]->key = "";
  373.         table[hindx]->val = NIL;
  374.         len--;
  375.     }
  376. }
  377.  
  378. void HashTable::printResult(int cases)
  379. {
  380.     if(colres == Chaining)
  381.         cout << "Chaining Method" << endl;
  382.     else if(colres == Double)
  383.         cout << "Double Hashing" << endl;
  384.     else if(colres == Custom)
  385.         cout << "Custom Probing" << endl;
  386.  
  387.     if(func == 1)
  388.         cout << "Using function 1" << endl;
  389.     else if(func == 2)
  390.         cout << "Using function 2" << endl;
  391.  
  392.     cout << "num of collision : " << nCol << endl;
  393.     cout << "average probes: " << (double)probe/(double)nSearch << endl;
  394.     cout << "nsearch: " << nSearch << endl;
  395.     cout << endl;
  396.     /*
  397.     for(int i=0; i<maxsize; i++) {
  398.         HashNode *node = table[i];
  399.         while(node != nullptr) {
  400.             if(!node->key.empty())
  401.                 cout << node->key << "  ";
  402.             node = node->next;
  403.         }
  404.         cout << endl;
  405.     }*/
  406. }
  407.  
  408. int main()
  409. {
  410.     int n;
  411.     cout << "size of the table: ";
  412.     cin >> n;
  413.     string *word = new string[N];
  414.     string *searchword = new string[1000];
  415.     wordGenerator(word, N);
  416.     int indx = 0;
  417.     for(int i=0; i<1000; i++) {
  418.         indx = rand()%15 + indx;
  419.         searchword[i] = word[indx];
  420.         indx++;
  421.     }
  422.  
  423.     HashTable hashChainOne(n, 1, Chaining);
  424.     HashTable hashDoubleOne(n, 1, Double);
  425.     HashTable hashCustomOne(n, 1, Custom);
  426.  
  427.     HashTable hashChainTwo(n, 2, Chaining);
  428.     HashTable hashDoubleTwo(n, 2, Double);
  429.     HashTable hashCustomTwo(n, 2, Custom);
  430.  
  431.     ///**Chaining method**
  432.     for(int i=0; i<N; i++)
  433.         hashChainOne.inSert(word[i], i+1);
  434.     for(int i=0; i<1000; i++)
  435.         hashChainOne.seArch(searchword[i]);
  436.     hashChainOne.printResult(1000);
  437.  
  438.     for(int i=0; i<N; i++)
  439.         hashChainTwo.inSert(word[i], i+1);
  440.     for(int i=0; i<1000; i++)
  441.         hashChainTwo.seArch(searchword[i]);
  442.     hashChainTwo.printResult(1000);
  443.  
  444.     ///**Double Hashing method**
  445.     for(int i=0; i<N; i++)
  446.         hashDoubleOne.inSert(word[i], i+1);
  447.     for(int i=0; i<1000; i++)
  448.         hashDoubleOne.seArch(searchword[i]);
  449.     hashDoubleOne.printResult(1000);
  450.  
  451.     for(int i=0; i<N; i++)
  452.         hashDoubleTwo.inSert(word[i], i+1);
  453.     for(int i=0; i<1000; i++)
  454.         hashDoubleTwo.seArch(searchword[i]);
  455.     hashDoubleTwo.printResult(1000);
  456.  
  457.     ///**Custom Hashing method**
  458.     for(int i=0; i<N; i++)
  459.         hashCustomOne.inSert(word[i], i+1);
  460.     for(int i=0; i<1000; i++)
  461.         hashCustomOne.seArch(searchword[i]);
  462.     hashCustomOne.printResult(1000);
  463.  
  464.     for(int i=0; i<N; i++)
  465.         hashCustomTwo.inSert(word[i], i+1);
  466.     for(int i=0; i<1000; i++)
  467.         hashCustomTwo.seArch(searchword[i]);
  468.     hashCustomTwo.printResult(1000);
  469.  
  470.     return 0;
  471. }
  472.  
Add Comment
Please, Sign In to add comment