我有100-1001的随机数组,我转移到哈希表。 散列函数是n的mod(数组的大小)。 问题是,当我试图检查哈希表中的内容时,它向我显示了我在纸上计算的不同索引,所以我很困惑,如果它的工作正确与否。 另外,据我所知,哈希表的大小必须至少比数组大小大5%,但我找不到如何设置哈希表大小。我哪里弄错了? 我必须在此之后使用相同的哈希函数按地址搜索。
static void Main()
{
int n;
Console.WriteLine("Please enter array size");
n = Convert.ToInt32(Console.ReadLine());
Random rnd = new Random();
int[] a = new int[n + 4];
for (int i = 0; i < n; i++)
Console.Write("{0,4}", a[i] = rnd.Next(100, 1001));
// I have deleted code in the middle as there is certain type of search in array which works fine
// Now putting values to hash table
Hashtable Hashtable = new Hashtable();
int hashcode = n + ((n / 100) * 5);
int value;
int key;
for (int i = 0; i < n; i++)
{
value = a[i];
key = value % hashcode;
if (Hashtable[key] == null)
Hashtable.Add(key, value);
else
{
while (Hashtable[key] != null)
{
if (key == (hashcode - 1))
key = 0;
else
key++;
}
Hashtable.Add(key, value);
}
}
Console.WriteLine();
}
答案 0 :(得分:1)
关于哈希表如何在.NET中运行,似乎有点混乱。哈希表是关联列表。这意味着您可以通过其键检索值,这在数组或列表不起作用时很有用,因为您不通过索引访问值(例如,在缓存方案中)。为了快速访问存储的键/值对,哈希表内部计算密钥的哈希码,以便将数据存储在桶中。
您正在做的是从外部计算“哈希码” ,然后将其用作哈希表的键。哈希表的作用是计算该键的哈希码 以存储键/值对。我很确定这不是你想要做的。
我通常会建议您使用Dictionary<int, int>
,但您的情况有所不同。您的密钥直接来自您要存储的值,因此您的情况不适用于请求列表。我不确切地知道你想要实现什么,但你的情况看起来最适合HashSet
(这是一个使用哈希码来存储值的集合)。您可以覆盖密钥的GetHashCode
方法来更改散列方法,即使没有必要。在你的情况下,它甚至会降低哈希集的有效性,因为你的哈希方法不仅非常差,因为它的范围远远小于Int32
的范围,它也会导致很多冲突,你的哈希集必须解决。
由于您无法更改GetHashCode
的{{1}}方法,因此您必须为此创建一个包装器:
int
然后,您可以创建private struct HashCodeWrapper {
private readonly int value;
private readonly int n;
public int Value {
get {
return value;
}
}
public HashCodeWrapper(int value, int n) {
this.value = value;
this.n = n;
}
public override int GetHashCode() {
return value % (n + ((n / 100) * 5));
}
public override bool Equals(object obj) {
return (obj is HashCodeWrapper) && ((HashCodeWrapper)obj).value.Equals(value);
}
}
并将包装器添加到集合中。如果这对您不起作用,您必须实现自己的“哈希表”版本。
但是出于所有实际目的,只需使用HashSet<HashCodeWrapper>
并节省大量工作。