Guest User

Vikram Menon

a guest
Sep 16th, 2009
510
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.45 KB | None | 0 0
  1. /*
  2.  * Hashtable template, with collision resolution by chaining
  3.  * Input text file must hold comma separated values.
  4.  * Eg-
  5.  * name1, num1
  6.  * name2, num2
  7.  */
  8.  
  9. #include <iostream>
  10. #include <fstream>
  11. #include <math.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #define LEN 8               // length of the hash (bytes)
  16. #define NAME 30             // length of string to store a name
  17. #define BUF 200             // length of buffer to read from text file
  18. #define LIM 1000            // number of available pointers
  19.  
  20. using namespace std;
  21.  
  22. void hash(char*, char*, int);       // reduce the string to a hash
  23. int  key(char *h);          // reduce the hash to a numeric key
  24.  
  25. void string2Name(char*, char*);
  26. int  string2Num(char*);
  27.  
  28. /*
  29.  * Node of the hashtable.
  30.  * Must include the public fields:
  31.  * name (char[NAME])
  32.  * next (node*)
  33.  */
  34. class node
  35. {
  36.     int marks;
  37.  
  38. public:
  39.     char name[NAME];
  40.     node *next;         // link to next node in chain
  41.  
  42.     void input(char *nm, int mk)        // parameterised input
  43.     {
  44.         strcpy(name,nm);
  45.         marks = mk;
  46.         next = NULL;
  47.     }
  48.  
  49.     void output()               // display contents of node
  50.     {
  51.         cout<<"\nName: ";
  52.         puts(name);
  53.         cout<<"Marks: "<<marks<<"\n";
  54.     }
  55. };
  56.  
  57. /*
  58.  * Hashtable template. Eg-
  59.  * htable<node> myHT;
  60.  *
  61.  * NOTE:
  62.  * Use 'new' to create nodes and call add_node() to enter it into the hashtable.
  63.  * Calling del_node() on a node automatically deletes it.
  64.  */
  65. template <class T>          // Hashtable template
  66. class htable
  67. {
  68.     T *arr[LIM];
  69.  
  70. public:
  71.     htable()                        // constructor
  72.     {
  73.         for(int i=0; i < LIM; i++)
  74.             arr[i] = NULL;
  75.     }
  76.  
  77.     void add_node(T *in)                    // add an entry
  78.     {
  79.         char h[LEN + 1];
  80.         hash(in->name, h, LEN);
  81.         int n = key(h)%LIM;
  82.         if(arr[n] == NULL)
  83.             arr[n] = in;
  84.         else
  85.         {
  86.             T *p = arr[n];
  87.             while(p->next != NULL && strcmp(p->name,in->name))  // chaining the node
  88.                 p = p->next;
  89.             if(!strcmp(p->name,in->name))
  90.             {
  91.                 cout<<"\nDuplicate entry!\n";
  92.                 return;
  93.             }
  94.             p->next = in;
  95.         }
  96.     }
  97.  
  98.     T *find_node(char *nam)                 // search an entry
  99.     {
  100.         char h[LEN + 1];
  101.         hash(nam, h, LEN);
  102.         int n = key(h)%LIM;
  103.         T *p;
  104.         for(p = arr[n]; p != NULL && strcmp(p->name,nam); p = p->next);
  105.         if(p)
  106.         {
  107.             cout<<"\nThe entry was found!\n";
  108.             p->output();
  109.             return p;
  110.         }
  111.         else
  112.         {
  113.             cout<<"\nEntry not found!\n";
  114.             return NULL;
  115.         }
  116.     }
  117.  
  118.     void del_node(char *nam)                // delete an entry
  119.     {
  120.         char h[LEN + 1];
  121.         hash(nam, h, LEN);
  122.         int n = key(h)%LIM;
  123.         T *t = NULL, *p;
  124.         for(p = arr[n]; p != NULL && strcmp(p->name,nam);)
  125.         {
  126.             t = p;
  127.             p = p->next;
  128.         }
  129.         if(p)
  130.         {
  131.             p->output();
  132.             if(t)
  133.                 t->next = p->next;
  134.             else
  135.                 arr[n] = NULL;
  136.             delete p;
  137.             cout<<"\nThe entry was deleted!\n";
  138.         }
  139.         else
  140.             cout<<"\nEntry not found!\n";
  141.     }
  142.  
  143.     void display()                      // show all entries
  144.     {
  145.         T *p;
  146.         for(int i=0; i < LIM; i++)
  147.         {
  148.             p = arr[i];
  149.             while(p != NULL)            // traverse the chain
  150.             {
  151.                 p->output();
  152.                 p = p->next;
  153.             }
  154.         }
  155.     }
  156.  
  157.     void feed_data(char **s, int num)       // input from string array
  158.     {
  159.         T *np;
  160.         char nm[NAME];
  161.         int mk;
  162.         for(int i=0;i<num;i++)
  163.         {
  164.             np = new T;
  165.             string2Name(s[i], nm);
  166.             mk = string2Num(s[i]);
  167.             np->input(nm, mk);
  168.             add_node(np);
  169.         }
  170.     }
  171. };
  172.  
  173. /* Returns: void
  174.  *
  175.  * Function to reduce a string to a hash of the requested length.
  176.  * Hash only contains the letters: a-z
  177.  * (hval must be at least LEN + 1 bytes)
  178.  */
  179. void hash(char *str, char *hval, int Max)   // generate the hash
  180. {
  181.     int i, j = 0, k, l = strlen(str), m;
  182.     long temp;
  183.     for(i=0; i < Max; i++)
  184.         hval[i] = 'a';
  185.     hval[Max] = '\0';
  186.     for(i=0; i < l; i++)
  187.     {
  188.         if(str[i] > 64 && str[i] < 91)
  189.             str[i] += 32;
  190.         if(str[i] < 97 || str[i] > 122)
  191.             continue;
  192.         k = j + str[i] - 97;
  193.         for(; j <= k; j++)              // alter values from position j to k
  194.         {
  195.             m = j%Max;
  196.             temp = hval[m] + (i + 1)*(m + 1)*str[i];
  197.             if(temp >= 123)
  198.                 temp = 97 + (temp - 123)%26;
  199.             hval[m] = temp;
  200.         }
  201.         j %= Max;
  202.     }
  203. }
  204.  
  205. /* Returns: int
  206.  * key value of the hash
  207.  *
  208.  * Function to reduce the hash to a numeric key
  209.  */
  210. int key(char *h)    // reduce hash to key
  211. {
  212.     int ret = 0;
  213.     for(int i=0; i < LEN; i++)
  214.         ret += (h[i] - 97)*(1 + LEN/(i+1));
  215.     return ret;
  216. }
  217.  
  218. /* Returns: void
  219.  *
  220.  * Function to retrieve the name at the start of a string
  221.  * (nam must be exactly NAME bytes)
  222.  */
  223. void string2Name(char *str, char *nam)  // get name from string
  224. {
  225.     int l = strlen(str);
  226.     for(int i=0; i < l; i++)
  227.     {
  228.         if(str[i] != ',')               // name and marks are comma separated
  229.             nam[i] = str[i];
  230.         else
  231.         {
  232.             nam[i] = '\0';
  233.             break;
  234.         }
  235.     }
  236. }
  237.  
  238. /* Returns: int
  239.  * integer at the end of the string
  240.  *
  241.  * Function to retrieve the number at the end of the string
  242.  * (Negative integers allowed)
  243.  */
  244. int string2Num(char *str)           // get integer from string
  245. {
  246.     int res = 0, l = strlen(str);
  247.     for(int i=l-1; i >= 0; i--)
  248.     {
  249.         if(str[i]=='-')             // negative integer
  250.             res *= -1;
  251.         if(str[i] > 47 && str[i] < 58)
  252.             res += (str[i] - 48)*pow(10, l-i-1);
  253.         else break;
  254.     }
  255.     return res;
  256. }
  257.  
  258. int filereader(char **s)            //Read lines from a file to array of strings
  259. {
  260.     fstream f;
  261.     char fname[NAME];
  262.     cout<<"\nEnter name of text file (without .txt): ";
  263.     cin>>fname;
  264.     f.open(fname,ios::in);
  265.     if(f.fail())
  266.     {
  267.         cout<<"\nERROR: Could not open file!\n";
  268.         exit(0);
  269.     }
  270.     int num = 0;
  271.     while(f.good())                 // read file contents to string array
  272.     {
  273.         s[num] = new char[BUF];
  274.         f.getline(s[num], BUF);
  275.         num++;
  276.     }
  277.     f.close();
  278.     return num;
  279. }
  280.  
  281. int main()                  // build and use htable<node>
  282. {
  283.     char str[NAME], **s;
  284.     node *np;
  285.     htable<node> ht;
  286.     int c;
  287.     do                          // program loop
  288.     {
  289.         cout<<"\n\nHASHTABLE PROGRAM:\n\n1. Add new entry\n2. Find an entry\n"
  290.             <<"3. Delete an entry\n4. Add from file\n5. Display all contents\n";
  291.         cin>>c;
  292.         switch(c)
  293.         {
  294.             case 1:             // add a new entry
  295.             {
  296.                 np = new node;
  297.                 cout<<"\nEnter name (no spaces): ";
  298.                 cin>>str;
  299.                 cout<<"Enter marks: ";
  300.                 cin>>c;
  301.                 np->input(str, c);
  302.                 ht.add_node(np);
  303.                 break;
  304.             }
  305.             case 2:             // search for an entry
  306.             {
  307.                 cout<<"\nEnter the name to search: ";
  308.                 cin>>str;
  309.                 ht.find_node(str);
  310.                 break;
  311.             }
  312.             case 3:             // delete an entry
  313.             {
  314.                 cout<<"\nEnter the name to delete: ";
  315.                 cin>>str;
  316.                 ht.del_node(str);
  317.                 break;
  318.             }
  319.             case 4:             // read comma separated data from file
  320.             {
  321.                 c = filereader(s);
  322.                 ht.feed_data(s, c);
  323.                 break;
  324.             }
  325.             case 5: ht.display();   // display entire hashtable
  326.             default:;
  327.         }
  328.         cout<<"\nDo you want to continue? (0/1)";
  329.         cin>>c;
  330.     }while(c != 0);
  331. }
  332.  
Advertisement
Add Comment
Please, Sign In to add comment