数组比较作为C#中的字典键 [英] Array comprasion as Dictionary keys in C#

查看:74
本文介绍了数组比较作为C#中的字典键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个表示n维数组的类,但是在哪里可以对其元素进行交换访问.例如:a[new[] {4, 7, 55}] == a[new[] {55, 4, 7}]

I want to create class representing n-dimensional array, but where is a commutative access to its elements. e.g: a[new[] {4, 7, 55}] == a[new[] {55, 4, 7}]

我编写这段代码,在其中实现IEqualityComparer接口,以便按键(它们是数组)的实际内容(而不是引用)比较它们.

I write this code, where I implement interface IEqualityComparer in order to compare keys (which are arrays) by their real content, but not refs.

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();
    }
}

但是当我开始使用此类时,我遇到一个异常:"System.Collections.Generic.KeyNotFoundException:字典中不存在给定的键."在接下来的两种情况下,当我尝试将元素输出到控制台时,都会发生此异常:

But when I start to use this class I encounter an exception: "System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary." This exception occurs in next both cases when I try to output the element to console:

NArray a = new NArray();
a[new[] { 1, 3, 2 }] = 4;

Console.WriteLine(a [new [] {3,2,1}]);//错误

Console.WriteLine(a[new[] { 3, 2, 1 }]); //error

NArray b = new NArray();
b[new[] { 1, 2, 3 }] = 4;
Console.WriteLine(b[new[] { 1, 2, 3 }]);    //error

那么造成该问题的原因是什么,我该如何解决?

So what is the cause of that problem and how could I fix it?

推荐答案

这是因为您对GetHashCode的实现不正确:具有相同顺序的相同项的两个不同数组通常不会具有相同的哈希码(因为值不考虑在内),因此永远不会调用Equals.

That's because your implementation of GetHashCode is incorrect: two different arrays with the same items in the same order usually won't have the same hashcode (because the values are not taken into account), so Equals is never called.

您需要实现GetHashCode,该实现将数组中的值考虑在内:

You need an implementation of GetHashCode that takes the values in the array into account:

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));
    }
}

这篇关于数组比较作为C#中的字典键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆