C# C语言中作为字典键的数组压缩#
我想创建一个表示n维数组的类,但其中是对其元素的交换访问。e、 g:C# C语言中作为字典键的数组压缩#,c#,arrays,C#,Arrays,我想创建一个表示n维数组的类,但其中是对其元素的交换访问。e、 g:a[new[]{4,7,55}]==a[new[]{55,4,7}] 我编写了这段代码,在这里我实现了接口IEqualityComparer,以便通过键(数组)的实际内容(而不是引用)来比较键 using System; using System.Collections.Generic; using System.Linq; class NArray { public int this[int[] x] {
a[new[]{4,7,55}]==a[new[]{55,4,7}]
我编写了这段代码,在这里我实现了接口IEqualityComparer,以便通过键(数组)的实际内容(而不是引用)来比较键
using System;
using System.Collections.Generic;
using System.Linq;
class NArray
{
public int this[int[] x]
{
get
{
Array.Sort(x);
return array[x];
}
set
{
Array.Sort(x);
array[x] = value;
}
}
public void Remove(int[] x)
{
Array.Sort(x);
array.Remove(x);
}
Dictionary<int[], int> array = new Dictionary<int[], int>(new ArrCmpr());
}
class ArrCmpr : IEqualityComparer<int[]>
{
public bool Equals(int[] a, int[] b)
{
return a.Length == b.Length && Enumerable.Range(0, a.Length).All(i => a[i] == b[i]);
}
public int GetHashCode(int[] a)
{
return a.GetHashCode();
}
}
Console.WriteLine(a[new[]{3,2,1}])//错误
那么这个问题的原因是什么?我该如何解决它呢?这是因为您对
GetHashCode
的实现是不正确的:两个具有相同项目的不同数组以相同的顺序通常不会具有相同的hashcode(因为没有考虑值),因此永远不会调用Equals
您需要一个GetHashCode
的实现,该实现将数组中的值考虑在内:
class ArrCmpr : IEqualityComparer<int[]>
{
public bool Equals(int[] a, int[] b)
{
return a.SequenceEqual(b);
}
public int GetHashCode(int[] a)
{
return a.Aggregate(0, (acc, i) => unchecked(acc * 457 + i * 389));
}
}
类ArrCmpr:IEqualityComparer
{
公共布尔等于(int[]a,int[]b)
{
返回a.a(b);
}
公共int GetHashCode(int[]a)
{
返回a.Aggregate(0,(acc,i)=>未选中(acc*457+i*389));
}
}
在我看来,GetHashCode必须更改,因为它只返回数组对象的哈希代码,考虑到您每次使用新的哈希代码都会不同,即使内容相同。因为您使用字典存储数组,所以需要检查键是否已经存在,只有这样,您才能使用[]运算符访问它,否则,如果您尝试访问不存在的密钥,将引发异常
// your get function
if(array.ContainsKey(x))
return array[x];
else // do something like return null
return null;
// your set function
if(array.ContainsKey(x))
array[x] = value;
else
array.Add(x, value);
最初我忽略了GetHashCode方法,非常感谢!不幸的是,我一开始忽略了GetHashCode方法。但现在我纠正了我的错误。非常感谢你!
class ArrCmpr : IEqualityComparer<int[]>
{
public bool Equals(int[] a, int[] b)
{
return a.SequenceEqual(b);
}
public int GetHashCode(int[] a)
{
return a.Aggregate(0, (acc, i) => unchecked(acc * 457 + i * 389));
}
}
// your get function
if(array.ContainsKey(x))
return array[x];
else // do something like return null
return null;
// your set function
if(array.ContainsKey(x))
array[x] = value;
else
array.Add(x, value);