0

In the below scenario how can I handle or implement collision in C# using the Hashtable class? If the 'Key' value is same I am getting an "Argument Exception".

static void Main(string[] args)
    {
        Console.Write("Enter a string:");
        string input = Console.ReadLine();            

        checkString(input);            

        Console.ReadLine();
    }

    static void checkString(string input)
    {
        Hashtable hashTbl = new Hashtable();                                                            

        foreach(char c in input)
        {    
            hashTbl.Add(c.GetHashCode(), c);
        }

        printHash(hashTbl);
    }

    static void printHash(Hashtable hash)
    {
        foreach(int key in hash.Keys)
        {
            Console.WriteLine("Key: {0} Value: {1}",key,hash[key]);
        }
    }

My Expectation: What do I need to do in the 'Value' argument to get around the 'Collision' issue. I am trying to check if the string consists of unique characters.

Prakazz
  • 421
  • 1
  • 8
  • 21

3 Answers3

2

It seems you are misunderstanding how the Hashtable class works (and it has been deprecated since 2005 - use Dictionary<K,V> instead, but its behavior here is identical).

It seems you're expecting it to be your job to get an object's hashcode and add it to the hashtable. It isn't. All you need to do is add the object you want to use as key (each character), and the internal implementation will extract the hashcode.

However, what you're actually doing won't work even if you added the key object yourself. You're taking an input string (say, "test"), and for each character, you're adding it to the hashtable as a key. But since keys are, by definition, unique, you'll be adding the character 't' twice (it shows up twice in the input), so you'll get an exception.

Avner Shahar-Kashtan
  • 14,492
  • 3
  • 37
  • 63
0

As previously stated you should probably switch to the Dictionary<TKey, TValue> class for this.

If you want to get around the collission issue, then you have to check the key for existence.

Dictionary<string, object> dictValues = new Dictionary<string, object>();

Then you can use check for collission:

if (dictValues.ContainsKey(YourKey)) 
{ 
     /* ... your collission handling here ... */ 
}
else
{
     // No collission
}

Another possibility would be, if you are not interested in preserving previous values for the same key:

dictValues[YourKey] = YourValue;

This will add the key entry if it is not there already. If it is, it will overwrite its value with the given input.

0

I am trying to check if the string consists of unique characters.

Then you need keys only without values, that's what HashSet<T> is for.

var chars = new HashSet<char>();
foreach (char c in input)
{
    if (chars.Contains(c))
    {
        // c is not unique
    }
    else
    {
        chars.Add(c);
    }
}

But I'd prefer usin LINQ in this case:

var hasUniqueChars = input.Length == input.Distinct().Count();
György Kőszeg
  • 17,093
  • 6
  • 37
  • 65