Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Collections;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- //Leif Svensson
- //BIT - 265
- //Final project
- //March 18, 2014
- namespace Final
- {
- class HashTable
- {
- List<string> dictList;
- LinkedList<string>[] HashOneTable;
- LinkedList<string>[] HashTwoTable;
- Random r;
- /// <summary>
- /// Running everything out of the constructor as to minimize clutting within Main
- /// </summary>
- /// <param name="inputFile"></param>
- public HashTable(string inputFile)
- {
- string dictFile;
- string[] words = new string[2800];
- r = new Random();
- dictList = new List<string>();
- try
- {
- using (StreamReader file = new StreamReader(inputFile))
- {
- dictFile = file.ReadToEnd();
- string[] dictArray = dictFile.Split(new string[] { "\r\n", "\n", "\r", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
- dictList = dictArray.ToList<string>();
- foreach (string s in dictArray)
- {
- foreach (char c in s)
- {
- if (!(c >= 'a' && c <= 'z'))
- {
- Console.WriteLine("Bad char: {0}", c);
- }
- }
- }
- for (int i = 0; i < words.Length; i++)
- {
- int randIndex = r.Next(dictList.Count);
- words[i] = dictList.ElementAt(randIndex);
- }
- Debug.Assert(words.Length == 2800, "Words" + words.Length);
- HashOneTable = new LinkedList<string>[(words.Length / 4) + 1];
- HashTwoTable = new LinkedList<string>[(words.Length / 4) + 1];
- this.BuildHashTable(words, HashOneTable, HashOne);
- this.BuildHashTable(words, HashTwoTable, HashTwo);
- bool fContinue = true;
- while (fContinue)
- {
- Console.WriteLine();
- Console.WriteLine("\t\t\t-----Custom Hash Table-----");
- Console.WriteLine();
- Console.WriteLine(" 1.) Print Hash Table One ");
- Console.WriteLine(" 2.) Print Hash Table Two ");
- Console.WriteLine(" 3.) Get the length of the shortest list in each Hash Table.");
- Console.WriteLine(" 4.) Get the length of the longest list in each Hash Table.");
- Console.WriteLine(" 5.) Get the average length each list in each Hash Table.");
- Console.WriteLine(" 6.) Get the standard deviation of the length of lists.");
- Console.WriteLine(" 7.) Read my summary of the program.");
- Console.WriteLine(" 8.) Exit the program.");
- Console.WriteLine();
- Console.WriteLine("Type in the number corresponding to your choice, then press the 'Enter' key");
- Console.WriteLine();
- Console.Write("> ");
- int choice;
- if (!Int32.TryParse(Console.ReadLine(), out choice))
- {
- Console.Clear();
- Console.WriteLine();
- Console.WriteLine("You need to type in an integer!");
- Console.WriteLine("\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- continue;
- }
- if (choice < 0 || choice > 9)
- {
- Console.Clear();
- Console.WriteLine();
- Console.WriteLine("You need to type in one of choices above! You typed in: {0}", choice);
- Console.WriteLine("\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- continue;
- }
- Console.Clear();
- switch (choice)
- {
- case 1:
- this.PrintHashTable(HashOneTable);
- Console.WriteLine("Press any key to continue!");
- Console.WriteLine("\n\n\n");
- Console.ReadKey();
- Console.Clear();
- break;
- case 2:
- this.PrintHashTable(HashTwoTable);
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 3:
- Console.WriteLine();
- Console.WriteLine("The shortest length of each list is:\n");
- Console.Write(" Hash Table One: {0}",this.GetMin(HashOneTable) + Environment.NewLine);
- Console.Write(" Hash Table Two: {0}", this.GetMin(HashTwoTable));
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 4:
- Console.WriteLine();
- Console.WriteLine("The longest length of each list is:\n");
- Console.Write(" Hash Table One: {0}",this.GetMax(HashOneTable) + Environment.NewLine);
- Console.Write(" Hash Table Two: {0}", this.GetMax(HashTwoTable));
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 5:
- Console.WriteLine();
- Console.WriteLine("The average length of each list is:\n");
- Console.Write(" Hash Table One: {0}",this.GetAverage(HashOneTable) + Environment.NewLine);
- Console.Write(" Hash Table Two: {0}", this.GetAverage(HashTwoTable));
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 6:
- Console.WriteLine();
- Console.WriteLine("The standard deviation of each list is:\n");
- Console.Write(" Hash Table One: {0}",this.GetStdDev(HashOneTable) + Environment.NewLine);
- Console.Write(" Hash Table Two: {0}", this.GetStdDev(HashTwoTable));
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 7:
- Console.WriteLine();
- Console.WriteLine("\t\t\t\t-----Summary-----");
- Console.WriteLine();
- Console.WriteLine("\tWhat I noticed with the first hash function was that it was not as" +
- "\naccurate as the second function due squaring the first character. \nThe second hash" +
- "function is closest to the load factor because it does\nnot return such high numbers." +
- "\n\n\tThe closest the first hash funtion gets to\nthe load factor is approximately 15.0 while" +
- "the second is approximately 4.0.\nThe second hash function proves to be a much more effecient" +
- "method for\nbuilding a hash table as you run a lot lower risk of overflowing data\ntypes and " +
- "maintain program specifications.");
- Console.WriteLine("\n\n\n");
- Console.WriteLine("Press any key to continue!");
- Console.ReadKey();
- Console.Clear();
- break;
- case 8:
- fContinue = false;
- break;
- }
- }
- }
- }
- catch (Exception e)
- {
- Console.WriteLine("\nFile could not be found!");
- Console.WriteLine(e.Message);
- }
- }
- public void PrintHashTable(LinkedList<string>[] list)
- {
- for (int i = 0; i < list.Length; i++)
- {
- for (int j = 0; j < list[i].Count; j++)
- {
- Console.Write(list[i].Count + ": " + list[i].ElementAt(j) + " ");
- Console.WriteLine();
- }
- Console.WriteLine();
- }
- }
- /// <summary>
- /// First time I have used Func<>, really made things a lot easier.
- /// This passes takes the words array which was populated by streamreader,
- /// and builds the buckets with each hash function.
- /// </summary>
- /// <param name="array"></param>
- /// <param name="hash"></param>
- /// <param name="hashFunction"></param>
- public void BuildHashTable(string[] array, LinkedList<string>[] hash, Func<string, long> hashFunction)
- {
- for (int i = 0; i < hash.Length; i++)
- {
- hash[i] = new LinkedList<string>();
- }
- foreach (string w in array)
- {
- hash[hashFunction(w)].AddFirst(w);
- }
- }
- /// <summary>
- /// Not as accurate because of Pow. Sorts better alphabetically because
- /// you are only looking at the first two numbers.
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public long HashOne(string key)
- {
- if (key.Length == 1)
- {
- long index = (int)Math.Pow(key.ElementAt(0), 2);
- index %= 701;
- return (index - 1);
- }
- else
- {
- int index = 0;
- int char1 = key.ElementAt(index);
- while (!(char1 >= 'a' && char1 <= 'z'))
- {
- index++;
- }
- char1 = key.ElementAt(index) - (int)'a' + 1;
- Debug.Assert(char1 >= 1 && char1 <= 26, "char1" + char1.ToString());
- index++;
- int char2 = key.ElementAt(index);
- while (!(char2 >= 'a' && char2 <= 'z'))
- {
- index++;
- }
- char2 = key.ElementAt(index) - (int)'a' + 1;
- Debug.Assert(char2 >= 1 && char2 <= 26, "char2" + char2.ToString());
- int hash = (int)Math.Pow(char1, 2) + char2;
- if (hash == 702)
- {
- Debug.Assert(hash >= 1 && hash <= 701, "hash" + hash.ToString());
- }
- hash -= 1;
- Debug.Assert(hash >= 0 && hash <= 700, "hash (minus 1)" + hash.ToString());
- return hash;
- }
- }
- /// <summary>
- /// A lot closer to the load factor. Much more effecient function call.
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public long HashTwo(string key)
- {
- long hash = 1;
- for (int i = 0; i < key.Length; i++)
- {
- long letter = (long)key.ElementAt(i) - (long)'a' + 1L;
- Debug.Assert(letter >= 1 && letter <= 26, "letter: " + letter);
- if (!(letter >= 1 && letter <= 26))
- {
- Console.WriteLine("letter: " + letter);
- }
- Debug.Assert(letter >= 1 && letter <= 26, "letter" + letter.ToString());
- if (hash * letter < 0)
- {
- break;
- }
- else
- {
- hash *= letter;
- }
- }
- if (hash < 0)
- {
- Console.WriteLine(hash);
- }
- Debug.Assert(hash >= 0, "hash positive?" + hash);
- hash %= 701L;
- Debug.Assert(hash >= 0 && hash <= 700, "last hash" + hash);
- return hash;
- }
- public int GetMin(LinkedList<string>[] hash)
- {
- int min;
- int index = 0;
- while (hash[index].Count == 0)
- index++;
- min = hash[index].Count;
- for (int i = 0; i < hash.Length; i++)
- {
- if (hash[i].Count < min && hash[i].Count > 0)
- {
- min = hash[i].Count;
- }
- }
- return min;
- }
- public int GetMax(LinkedList<string>[] hash)
- {
- int max;
- int index = 0;
- while (hash[index].Count == 0)
- index++;
- max = hash[index].Count;
- for (int i = index; i < hash.Length; i++)
- {
- if (hash[i].Count > max && hash[i].Count > 0)
- {
- max = hash[i].Count;
- }
- }
- return max;
- }
- public double GetAverage(LinkedList<string>[] hash)
- {
- int sum = 0;
- int numList = 0;
- for (int i = 0; i < hash.Length; i++)
- {
- if (hash[i].Count != 0)
- {
- sum += hash[i].Count;
- numList++;
- }
- }
- return ((double)sum / numList);
- }
- public double GetStdDev(LinkedList<string>[] hash)
- {
- double mean = 0;
- double avg = this.GetAverage(hash);
- for (int i = 0; i < hash.Length; i++)
- {
- mean += Math.Pow(avg - hash[i].Count, 2);
- }
- int length = 0;
- for (int i = 0; i < hash.Length; i++)
- {
- if (hash[i].Count > 0)
- {
- length++;
- }
- }
- return Math.Sqrt(mean / length);
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Directory.SetCurrentDirectory(@"C:\Users\College\BIT265\Final");
- string inputFile = @"words.txt";
- HashTable ht = new HashTable(inputFile);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment