ski900

Custom Hash Table

Mar 21st, 2014
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.28 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. //Leif Svensson
  10. //BIT - 265
  11. //Final project
  12. //March 18, 2014
  13. namespace Final
  14. {
  15.     class HashTable
  16.     {
  17.         List<string> dictList;
  18.         LinkedList<string>[] HashOneTable;
  19.         LinkedList<string>[] HashTwoTable;
  20.         Random r;
  21.         /// <summary>
  22.         /// Running everything out of the constructor as to minimize clutting within Main
  23.         /// </summary>
  24.         /// <param name="inputFile"></param>
  25.         public HashTable(string inputFile)
  26.         {
  27.             string dictFile;
  28.             string[] words = new string[2800];
  29.             r = new Random();
  30.             dictList = new List<string>();
  31.  
  32.             try
  33.             {
  34.                 using (StreamReader file = new StreamReader(inputFile))
  35.                 {
  36.                     dictFile = file.ReadToEnd();
  37.                     string[] dictArray = dictFile.Split(new string[] { "\r\n", "\n", "\r", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
  38.                     dictList = dictArray.ToList<string>();
  39.  
  40.                     foreach (string s in dictArray)
  41.                     {
  42.                         foreach (char c in s)
  43.                         {
  44.                             if (!(c >= 'a' && c <= 'z'))
  45.                             {
  46.                                 Console.WriteLine("Bad char: {0}", c);
  47.                             }
  48.                         }
  49.                     }
  50.  
  51.                     for (int i = 0; i < words.Length; i++)
  52.                     {
  53.                         int randIndex = r.Next(dictList.Count);
  54.                         words[i] = dictList.ElementAt(randIndex);
  55.                     }
  56.  
  57.                     Debug.Assert(words.Length == 2800, "Words" + words.Length);
  58.  
  59.                     HashOneTable = new LinkedList<string>[(words.Length / 4) + 1];
  60.                     HashTwoTable = new LinkedList<string>[(words.Length / 4) + 1];
  61.  
  62.                     this.BuildHashTable(words, HashOneTable, HashOne);
  63.                     this.BuildHashTable(words, HashTwoTable, HashTwo);
  64.  
  65.                     bool fContinue = true;
  66.  
  67.                     while (fContinue)
  68.                     {
  69.                         Console.WriteLine();
  70.                         Console.WriteLine("\t\t\t-----Custom Hash Table-----");
  71.                         Console.WriteLine();
  72.                         Console.WriteLine(" 1.) Print Hash Table One ");
  73.                         Console.WriteLine(" 2.) Print Hash Table Two ");
  74.                         Console.WriteLine(" 3.) Get the length of the shortest list in each Hash Table.");
  75.                         Console.WriteLine(" 4.) Get the length of the longest list in each Hash Table.");
  76.                         Console.WriteLine(" 5.) Get the average length each list in each Hash Table.");
  77.                         Console.WriteLine(" 6.) Get the standard deviation of the length of lists.");
  78.                         Console.WriteLine(" 7.) Read my summary of the program.");
  79.                         Console.WriteLine(" 8.) Exit the program.");
  80.                         Console.WriteLine();
  81.                         Console.WriteLine("Type in the number corresponding to your choice, then press the 'Enter' key");
  82.                         Console.WriteLine();
  83.                         Console.Write("> ");
  84.  
  85.                         int choice;
  86.  
  87.                         if (!Int32.TryParse(Console.ReadLine(), out choice))
  88.                         {
  89.                             Console.Clear();
  90.                             Console.WriteLine();
  91.                             Console.WriteLine("You need to type in an integer!");
  92.                             Console.WriteLine("\n\n");
  93.                             Console.WriteLine("Press any key to continue!");                            
  94.                             Console.ReadKey();
  95.                             Console.Clear();
  96.                             continue;
  97.                         }
  98.                         if (choice < 0 || choice > 9)
  99.                         {
  100.                             Console.Clear();
  101.                             Console.WriteLine();
  102.                             Console.WriteLine("You need to type in one of choices above!  You typed in: {0}", choice);
  103.                             Console.WriteLine("\n\n");
  104.                             Console.WriteLine("Press any key to continue!");
  105.                             Console.ReadKey();
  106.                             Console.Clear();
  107.                             continue;
  108.                         }
  109.                         Console.Clear();
  110.                         switch (choice)
  111.                         {
  112.                             case 1:
  113.                                 this.PrintHashTable(HashOneTable);
  114.                                 Console.WriteLine("Press any key to continue!");
  115.                                 Console.WriteLine("\n\n\n");
  116.                                 Console.ReadKey();
  117.                                 Console.Clear();
  118.                                 break;
  119.                             case 2:
  120.                                 this.PrintHashTable(HashTwoTable);
  121.                                 Console.WriteLine("\n\n\n");
  122.                                 Console.WriteLine("Press any key to continue!");
  123.                                 Console.ReadKey();
  124.                                 Console.Clear();
  125.                                 break;
  126.                             case 3:
  127.                                 Console.WriteLine();
  128.                                 Console.WriteLine("The shortest length of each list is:\n");
  129.                                 Console.Write("   Hash Table One: {0}",this.GetMin(HashOneTable) + Environment.NewLine);
  130.                                 Console.Write("   Hash Table Two: {0}", this.GetMin(HashTwoTable));
  131.                                 Console.WriteLine("\n\n\n");
  132.                                 Console.WriteLine("Press any key to continue!");
  133.                                 Console.ReadKey();
  134.                                 Console.Clear();
  135.                                 break;
  136.                             case 4:
  137.                                 Console.WriteLine();
  138.                                 Console.WriteLine("The longest length of each list is:\n");
  139.                                 Console.Write("   Hash Table One: {0}",this.GetMax(HashOneTable) + Environment.NewLine);
  140.                                 Console.Write("   Hash Table Two: {0}", this.GetMax(HashTwoTable));
  141.                                 Console.WriteLine("\n\n\n");
  142.                                 Console.WriteLine("Press any key to continue!");
  143.                                 Console.ReadKey();
  144.                                 Console.Clear();
  145.                                 break;
  146.                             case 5:
  147.                                 Console.WriteLine();
  148.                                 Console.WriteLine("The average length of each list is:\n");
  149.                                 Console.Write("   Hash Table One: {0}",this.GetAverage(HashOneTable) + Environment.NewLine);
  150.                                 Console.Write("   Hash Table Two: {0}", this.GetAverage(HashTwoTable));
  151.                                 Console.WriteLine("\n\n\n");
  152.                                 Console.WriteLine("Press any key to continue!");
  153.                                 Console.ReadKey();
  154.                                 Console.Clear();
  155.                                 break;
  156.                             case 6:
  157.                                 Console.WriteLine();
  158.                                 Console.WriteLine("The standard deviation of each list is:\n");
  159.                                 Console.Write("   Hash Table One: {0}",this.GetStdDev(HashOneTable) + Environment.NewLine);
  160.                                 Console.Write("   Hash Table Two: {0}", this.GetStdDev(HashTwoTable));
  161.                                 Console.WriteLine("\n\n\n");
  162.                                 Console.WriteLine("Press any key to continue!");
  163.                                 Console.ReadKey();
  164.                                 Console.Clear();
  165.                                 break;
  166.                             case 7:
  167.                                 Console.WriteLine();
  168.                                 Console.WriteLine("\t\t\t\t-----Summary-----");
  169.                                 Console.WriteLine();
  170.                                 Console.WriteLine("\tWhat I noticed with the first hash function was that it was not as" +
  171.                                     "\naccurate as the second function due squaring the first character. \nThe second hash" +
  172.                                     "function is closest to the load factor because it does\nnot return such high numbers." +
  173.                                     "\n\n\tThe closest the first hash funtion gets to\nthe load factor is approximately 15.0 while" +
  174.                                     "the second is approximately 4.0.\nThe second hash function proves to be a much more effecient" +
  175.                                     "method for\nbuilding a hash table as you run a lot lower risk of overflowing data\ntypes and " +
  176.                                     "maintain program specifications.");
  177.                                 Console.WriteLine("\n\n\n");
  178.                                 Console.WriteLine("Press any key to continue!");
  179.                                 Console.ReadKey();
  180.                                 Console.Clear();
  181.                                 break;
  182.                             case 8:
  183.                                 fContinue = false;
  184.                                 break;
  185.                         }
  186.                     }
  187.                 }
  188.             }
  189.             catch (Exception e)
  190.             {
  191.                 Console.WriteLine("\nFile could not be found!");
  192.                 Console.WriteLine(e.Message);
  193.             }
  194.            
  195.         }
  196.  
  197.         public void PrintHashTable(LinkedList<string>[] list)
  198.         {
  199.             for (int i = 0; i < list.Length; i++)
  200.             {
  201.                 for (int j = 0; j < list[i].Count; j++)
  202.                 {
  203.                     Console.Write(list[i].Count + ": " + list[i].ElementAt(j) + " ");
  204.                     Console.WriteLine();
  205.                 }
  206.                 Console.WriteLine();
  207.             }
  208.         }
  209.         /// <summary>
  210.         ///  First time I have used Func<>, really made things a lot easier.
  211.         ///  This passes takes the words array which was populated by streamreader,
  212.         ///  and builds the buckets with each hash function.
  213.         /// </summary>
  214.         /// <param name="array"></param>
  215.         /// <param name="hash"></param>
  216.         /// <param name="hashFunction"></param>
  217.         public void BuildHashTable(string[] array, LinkedList<string>[] hash, Func<string, long> hashFunction)
  218.         {
  219.             for (int i = 0; i < hash.Length; i++)
  220.             {
  221.                 hash[i] = new LinkedList<string>();
  222.             }
  223.  
  224.             foreach (string w in array)
  225.             {
  226.                 hash[hashFunction(w)].AddFirst(w);
  227.             }
  228.         }
  229.         /// <summary>
  230.         /// Not as accurate because of Pow. Sorts better alphabetically because
  231.         /// you are only looking at the first two numbers.
  232.         /// </summary>
  233.         /// <param name="key"></param>
  234.         /// <returns></returns>
  235.         public long HashOne(string key)
  236.         {
  237.             if (key.Length == 1)
  238.             {
  239.                 long index = (int)Math.Pow(key.ElementAt(0), 2);
  240.                 index %= 701;
  241.                 return (index - 1);
  242.             }
  243.             else
  244.             {
  245.                 int index = 0;
  246.                 int char1 = key.ElementAt(index);
  247.  
  248.                 while (!(char1 >= 'a' && char1 <= 'z'))
  249.                 {
  250.                     index++;
  251.                 }
  252.                 char1 = key.ElementAt(index) - (int)'a' + 1;
  253.                 Debug.Assert(char1 >= 1 && char1 <= 26, "char1" + char1.ToString());
  254.                
  255.                 index++;
  256.                 int char2 = key.ElementAt(index);
  257.                 while (!(char2 >= 'a' && char2 <= 'z'))
  258.                 {
  259.                     index++;
  260.                 }
  261.                 char2 = key.ElementAt(index) - (int)'a' + 1;
  262.                 Debug.Assert(char2 >= 1 && char2 <= 26, "char2" + char2.ToString());
  263.  
  264.                 int hash = (int)Math.Pow(char1, 2) + char2;
  265.                 if (hash == 702)
  266.                 {
  267.                     Debug.Assert(hash >= 1 && hash <= 701, "hash" + hash.ToString());
  268.                 }
  269.                 hash -= 1;
  270.  
  271.                 Debug.Assert(hash >= 0 && hash <= 700, "hash (minus 1)" + hash.ToString());
  272.  
  273.                 return hash;
  274.             }
  275.  
  276.         }
  277.         /// <summary>
  278.         /// A lot closer to the load factor. Much more effecient function call.
  279.         /// </summary>
  280.         /// <param name="key"></param>
  281.         /// <returns></returns>
  282.         public long HashTwo(string key)
  283.         {
  284.             long hash = 1;
  285.  
  286.             for (int i = 0; i < key.Length; i++)
  287.             {
  288.                 long letter = (long)key.ElementAt(i) - (long)'a' + 1L;
  289.                 Debug.Assert(letter >= 1 && letter <= 26, "letter: " + letter);
  290.  
  291.                 if (!(letter >= 1 && letter <= 26))
  292.                 {
  293.                     Console.WriteLine("letter: " + letter);
  294.                 }
  295.  
  296.                 Debug.Assert(letter >= 1 && letter <= 26, "letter" + letter.ToString());
  297.  
  298.                 if (hash * letter < 0)
  299.                 {
  300.                     break;
  301.                 }
  302.                 else
  303.                 {
  304.                     hash *= letter;
  305.                 }
  306.             }
  307.  
  308.             if (hash < 0)
  309.             {
  310.                 Console.WriteLine(hash);
  311.             }
  312.  
  313.             Debug.Assert(hash >= 0, "hash positive?" + hash);
  314.             hash %= 701L;
  315.  
  316.             Debug.Assert(hash >= 0 && hash <= 700, "last hash" + hash);
  317.  
  318.             return hash;
  319.         }
  320.  
  321.         public int GetMin(LinkedList<string>[] hash)
  322.         {
  323.             int min;
  324.             int index = 0;
  325.             while (hash[index].Count == 0)
  326.                 index++;
  327.             min = hash[index].Count;
  328.  
  329.             for (int i = 0; i < hash.Length; i++)
  330.             {
  331.                 if (hash[i].Count < min && hash[i].Count > 0)
  332.                 {
  333.                     min = hash[i].Count;
  334.                 }
  335.             }
  336.  
  337.             return min;
  338.         }
  339.  
  340.         public int GetMax(LinkedList<string>[] hash)
  341.         {
  342.             int max;
  343.             int index = 0;
  344.             while (hash[index].Count == 0)
  345.                 index++;
  346.             max = hash[index].Count;
  347.  
  348.             for (int i = index; i < hash.Length; i++)
  349.             {
  350.                 if (hash[i].Count > max && hash[i].Count > 0)
  351.                 {
  352.                     max = hash[i].Count;
  353.                 }
  354.             }
  355.             return max;
  356.         }
  357.  
  358.         public double GetAverage(LinkedList<string>[] hash)
  359.         {
  360.             int sum = 0;
  361.             int numList = 0;
  362.             for (int i = 0; i < hash.Length; i++)
  363.             {
  364.                 if (hash[i].Count != 0)
  365.                 {
  366.                     sum += hash[i].Count;
  367.                     numList++;
  368.                 }
  369.             }
  370.             return ((double)sum / numList);
  371.         }
  372.  
  373.         public double GetStdDev(LinkedList<string>[] hash)
  374.         {
  375.             double mean = 0;
  376.             double avg = this.GetAverage(hash);
  377.             for (int i = 0; i < hash.Length; i++)
  378.             {
  379.                 mean += Math.Pow(avg - hash[i].Count, 2);
  380.             }
  381.  
  382.             int length = 0;
  383.             for (int i = 0; i < hash.Length; i++)
  384.             {
  385.                 if (hash[i].Count > 0)
  386.                 {
  387.                     length++;
  388.                 }
  389.             }
  390.             return Math.Sqrt(mean / length);
  391.         }
  392.     }
  393.     class Program
  394.     {
  395.         static void Main(string[] args)
  396.         {
  397.             Directory.SetCurrentDirectory(@"C:\Users\College\BIT265\Final");
  398.             string inputFile = @"words.txt";
  399.             HashTable ht = new HashTable(inputFile);
  400.         }
  401.     }
  402. }
Advertisement
Add Comment
Please, Sign In to add comment