在c#中使用Hashtable类处理碰撞

时间:2017-10-01 13:05:04

标签: c# hashtable hash-collision

在下面的场景中,如何使用Hashtable类在C#中处理或实现冲突?如果'Key'值相同,我会得到一个“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]);
        }
    }

我的期望: 为了解决'碰撞'问题,我需要在'价值'论证中做些什么。我正在尝试检查字符串是否包含唯一字符。

3 个答案:

答案 0 :(得分:2)

您似乎误解了Hashtable类的工作方式(并且自2005年以来已被弃用 - 请改用Dictionary<K,V>,但此处的行为相同)。

您似乎期望它是您的作业来获取对象的哈希码并将其添加到哈希表中。事实并非如此。您需要做的就是添加要用作键的对象(每个字符),内部实现将提取哈希码。

但是,即使您自己添加了密钥对象,您实际执行的操作也无法正常工作。您正在获取输入字符串(例如,“test”),并且对于每个字符,您将其作为键添加到哈希表中。但是,根据定义,键是唯一的,你将两次添加字符't'(它在输入中显示两次),所以你会得到一个异常。

答案 1 :(得分:0)

如前所述,您可能应该切换到Dictionary<TKey, TValue>类。

如果你想解决这个问题,那么你必须检查存在的关键。

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

然后你可以使用check for collission:

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

另一种可能性是,如果您不想保留相同密钥的先前值:

dictValues[YourKey] = YourValue;

这将添加密钥条目(如果它尚未存在)。如果是,它将使用给定的输入覆盖其值。

答案 2 :(得分:0)

  

我正在尝试检查字符串是否包含唯一字符。

然后你只需要没有值的键,这是HashSet<T>的用途。

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

但在这种情况下,我更喜欢LINQ:

var hasUniqueChars = input.Length == input.Distinct().Count();