|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
[JAVA] Problema con la HashMap
Ciao, sto sviluppando un programma in Java che dovrebbe poi permettermi di elaborare tutta una serie di statistiche sulle estrazioni del Lotto (ho tutto lo storico dal 1939!). Ho già scritto parecchie classi ma sto avendo un problema con le HashMap e non riesco a capire perché. Naturalmente non posto tutto il codice (sarebbe troppo lungo) ma solo un pezzettino che ho rifatto a mo' di test:
Codice:
import java.lang.*;
import java.util.*;
class Terno
{
private byte[] numeri;
public Terno (byte n1, byte n2, byte n3)
{
numeri = new byte[3];
numeri[0] = n1;
numeri[1] = n2;
numeri[2] = n3;
}
public boolean equals (Terno t)
{
for (int i=0; i<3; i++)
if (numeri[i] != t.numeri[i])
return false;
return true;
}
public int hashCode ()
{
return ((int) numeri[2]) * 8100 + ((int) numeri[1]) * 90 + ((int) numeri[0]);
}
public String toString ()
{
return numeri[0] + ", " + numeri[1] + ", " + numeri[2];
}
}
public class ProvaTerno
{
public static void main (String argv[])
{
HashMap map = new HashMap (704880);
int n = 0;
for (byte i=1; i<=90; i++)
{
for (byte j=1; j<=90; j++)
{
for (byte k=1; k<=90; k++)
{
if (i != j && j != k && i != k)
{
Terno t = new Terno (k, j, i);
map.put (t, "aaa");
n++;
}
}
}
}
System.out.println ("Inseriti: " + n);
System.out.println ("Dimensione map: " + map.size ());
Terno t = new Terno ((byte) 5, (byte) 6, (byte) 7);
System.out.println (t.toString () + (map.containsKey (t) ? " contenuto" : " non contenuto"));
}
}
Nel main creo un HashMap con capacità di 704880 (che sono tutte le possibili combinazioni per un Terno, prendendo i numeri da 1 a 90 senza ripetizioni e ignorando l'ordine) e poi ci metto nell'HashMap tutte le combinazioni una per una. Come valore ho messo "aaa" tanto per provare (io dovrò metterci un altro oggetto). Alla fine vado a vedere se è contenuto il Terno 5,6,7. Avviando questo programma ottengo: Codice:
Inseriti: 704880 Dimensione map: 704880 5, 6, 7 non contenuto Codice:
map.put (new Terno ((byte) 5, (byte) 6, (byte) 7), "aaa"); Cosa può essere?? Forse il metodo hashCode non è giusto?? Uso il JDK 1.4.2_08-b03.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao
non ho avuto tempo e modo di verificare approfonditamente, ma vorrei esporti alcuni suggerimenti: - (C'entra poco) 704880 e' il numero di ripetizioni che ottieni TENENDO CONTO dell'ordine. Infatti ottieni questo numero scrivendo sia (1,2,3) sia (3,2,1) e considerandole differenti. Se dividi questo numero per 3! = 6, allora ottieni il numero delle combinazioni senza ripetizione che non tiene conto dell'ordine, cioe' proprio n!/(k! * (n-k)!) (il binomiale) = 117480 - Da quello che ho capito (purtroppo non sono ancora passato alla j5), questa HashMap va a controllare il "Riferimento" all'oggetto (visto che sei programmatore C/C++, il puntatore). Lui non sa quale procedure utilizzare per la comparazione e non la ridefinisci scrivendo una equals(obj) nell'oggetto da memorizzare. Ad orecchio, visto che la HashMap implementa la Map(), immagino che dovrai estendere la HashMap, mettendoci la TUA implementazione della suddetta procedura. Fammi sapere High Flying Sottovento |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Milano
Messaggi: 5707
|
di sicuro hai sbagliato a ridefinire "equals".
Devi fare l'overriding di quello con firma: public boolean equals(Object obj) |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
L'ho corretto e funziona. Grazie.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Ragazzi ... l'altro giorno che ho postato il codice penso di aver "cannato" (di brutto) il calcolo delle combinazioni, vero???
Ho ripreso una mia guida sul Calcolo Combinatorio ed ho visto che in realtà il numero esatto di combinazioni per un terno al lotto è di 117480 e non 704880!!! Infatti nel primo caso (117480) si parla di "combinazioni senza ripetizioni" mentre nel secondo caso (704880) si parla di "disposizioni senza ripetizioni". Io in effetti nel codice: Codice:
for (byte i=1; i<=90; i++)
{
for (byte j=1; j<=90; j++)
{
for (byte k=1; k<=90; k++)
{
if (i != j && j != k && i != k)
{
...
}
}
}
}
Ho quindi pensato un attimo a come eliminare anche le disposizioni ed ho modificato semplicemente il test così: Codice:
if (i < j && j < k)
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Penso sia meglio modificare i cicli for:
- il for piu' lento (i) va da 1 a 88; - il for medio (j) va da i + 1 a 89; - il for piu' veloce (k) va da j+1 a 90; High Flying Sottovento |
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jan 2001
Città: Milano
Messaggi: 5707
|
Quote:
esatto, è piu' elegante e ti risparmi un bel po' di iterazioni: Codice:
for (int i=1; i<=90; i++)
{
for (int j=i+1; j<=90; j++)
{
for (int k=j+1; k<=90; k++)
{
Terno t = new Terno ((byte)i, (byte)j, (byte)k);
map.put (t, "aaa");
n++;
}
}
}
|
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Giustissimo!!! Avrei dovuto pensarci subito (ci sarei arrivato eh!
Grazie a tutti e due (sottovento e kingv). ![]() In effetti così si risparmiano molto cicli (non che debba avere chissà quali prestazioni comunque, è un programmino "didattico", ma è sicuramente una miglioria).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Milano
Messaggi: 5707
|
ho riletto quello che ho scritto, gli indici giusti sono quelli suggeriti da sottovento, funzionalmente non cambia nulla ma ti risparmi ancora qualche ciclo
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 12:25.




















