2010-05-25 34 views
5

Tôi có thể sử dụng từ điển C# trên các lớp như mảng ??C# Từ điển của mảng

Dictionary<double[],double[]> 

tôi sợ rằng nó sẽ không có thể cho biết khi các mảng đều bình đẳng ...

EDIT:
sẽ phương pháp băm trong từ điển Làm mất cũng quan tâm của mảng? hoặc chỉ băm tài liệu tham khảo của họ?

+2

Nếu bạn có thể thỏa mãn sự tò mò của mình, doanh nghiệp cần chìa khóa là mảng gì? –

+0

Tôi đang thu thập cặp đầu vào-đầu ra (kích thước lớn) trong một vấn đề phân loại, trong đó các cặp lặp lại được tính trung bình bằng cách nào đó trước phân loại đào tạo ... – Betamoo

Trả lời

5

Đối với các khóa mảng, từ điển sẽ sử dụng các tham chiếu cho băm và bình đẳng, có thể không phải là những gì bạn muốn. Điều này khiến bạn có hai lựa chọn: thực hiện một lớp bao bọc cho double[], hoặc (tốt hơn) viết một cái gì đó mà thực hiện IEqualityComparer và chuyển nó tới hàm tạo Dictionary<T, T>.

+5

@BlueRaja, thực hiện một danh sách ' 'để so sánh bình đẳng và băm trên nội dung của nó? Tôi không nghĩ như vậy. –

3

Chỉ tham chiếu mảng sẽ được so sánh. Trong ví dụ sau, từ điển sẽ có mục mặc dù mảng a và b có cùng số các mục và các giá trị nhập đều bình đẳng:

double[] a = new[] { 1.0, 2.1, 3.2 }; 
double[] b = new[] { 1.0, 2.1, 3.2 }; 

Dictionary<double[], double[]> d = new Dictionary<double[], double[]>(); 

d[a] = new [] { 1.1 }; 
d[b] = new [] { 2.2 }; 

Console.WriteLine(d.Count); 
Console.WriteLine(d[b][0]); 
0

Tôi không nghĩ rằng có một mảng như là chìa khóa là một ý tưởng hay, đặc biệt nếu nó lớn và nếu logic bình đẳng của bạn dựa trên nội dung của mảng. Bởi vì mỗi khi bạn sẽ gọi GetHashCode, nó sẽ phải thực hiện các phép tính trên toàn bộ mảng, có thể mất chút thời gian nếu mảng lớn ...

Một giải pháp sẽ là bọc mảng trong một lớp sẽ lưu trữ hashcode cho đến khi dữ liệu được sửa đổi, do đó nó không được tính toán lại mỗi khi:

class ArrayWrapper<T> 
{ 
    private T[] _array; 
    public ArrayWrapper(T[] array) 
    { 
     _array = array; 
    } 

    private int? _hashcode; 
    public override int GetHashCode() 
    { 
     if (!_hashcode.HasValue) 
     { 
      _hashcode = ComputeHashCode(); 
     } 
     return _hashcode.Value; 
    } 

    public override bool Equals(object other) 
    { 
     // Your equality logic here 
    } 

    protected virtual int ComputeHashCode() 
    { 
     // Your hashcode logic here 
    } 

    public int Length 
    { 
     get { return _array.Length; } 
    } 

    public T this[int index] 
    { 
     get { return _array[index]; } 
     set 
     { 
      _array[index] = value; 
      // Invalidate the hashcode when data is modified 
      _hashcode = null; 
     } 
    } 
} 

vì vậy, từ điển của bạn sẽ là một Dictionary<ArrayWrapper<double>, ArrayWrapper<double>>. Tất nhiên, bạn có thể muốn thêm một số phương thức hoặc thuộc tính cho trình bao bọc (ví dụ: IList<T>)