C# C语言中作为字典键的数组压缩#

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] {

我想创建一个表示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]
    {
        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);