2010-05-25 38 views
5

Posso utilizzare C# del dizionario su classi come array ??C# Dizionario di array

Dictionary<double[],double[]> 

temo che non sarà in grado di dire quando le matrici sono uguali ...

EDIT:
Sarà il metodo di hashing nel dizionario preso bene la cura di array? o semplicemente tagliando i loro riferimenti?

+2

Se puoi soddisfare la mia curiosità, qual è l'esigenza aziendale di avere la chiave come matrice? –

+0

sto raccogliendo coppia di ingresso-uscita (di grandi dimensionalità) in un problema di classificazione, in cui le coppie ripetuti vengono mediati in qualche modo prima dell'allenamento classificatore ... – Betamoo

risposta

5

Per i tasti array, il dizionario utilizza i riferimenti per hashing e uguaglianza, che probabilmente non è ciò che si desidera. Questo ti lascia due possibilità: implementare una classe wrapper per double[] o (meglio) scrivere qualcosa che implementa IEqualityComparer e passarla al costruttore Dictionary<T, T>.

+5

@BlueRaja, fa un '' lista fare confronto di uguaglianza e di hashing sopra il suo contenuto? Non penso che lo faccia. –

3

Solo i riferimenti di matrice verranno confrontati. Nel seguente esempio, il dizionario avrà voci anche se le matrici A e B hanno lo stesso numero di voci ei valori di ingresso sono uguali:

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

non ritengo avente una matrice come chiave è una buona idea, specialmente se è grande e se la tua logica di uguaglianza è basata sul contenuto dell'array. Perché ogni volta che chiamerai il numero GetHashCode, dovrà eseguire calcoli sull'intero array, che può richiedere del tempo se l'array è grande ...

Una soluzione sarebbe quella di avvolgere l'array in una classe che memorizzerebbe il codice hash fino a quando i dati vengono modificati, in modo che non viene ricalcolato ogni volta:

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

così il dizionario sarebbe una Dictionary<ArrayWrapper<double>, ArrayWrapper<double>>. Naturalmente, potresti voler aggiungere alcuni metodi o proprietà al wrapper (ad esempio, implementare IList<T>)