Schwieriges Problem ?

Hi,

ich habe eine Hashtabelle mit vielen Einträgen, wobei der Key ein String und der Wert ein Integer ist. Jetzt möchte ich zufällige Einträge aus der Hashtabelle entnehmen. Wie mache ich das ?

Grüße,

Tris

Moin

Jetzt möchte ich
zufällige Einträge aus der Hashtabelle entnehmen. Wie mache
ich das ?

Hashtable hat ein Funktion „Enumeration
keys()“. Was da rauskommt ist in keiner speziellen Ordnung, also mehr oder weniger random.

cu

Hallo,

Hashtable hat ein Funktion „Enumeration
keys()“. Was da rauskommt ist in keiner speziellen Ordnung,
also mehr oder weniger random.

eigentlich meinte ich nur ein paar zufällige Einträge aus der Hashtabelle, also nicht alle.

Grüße,

Tris

Hi,

bist du dir sicher, dass eine Hashtable das Richtige ist für dich?
Wenn ich es richtig sehe, dann willst du eigentlich per Zufallszahl
einen String auswählen und der int-Wert ist sozusagen nur ein Attribut.

Dann mach doch soetwas.

public class Entry{
private Object key;
private Object value;

public Entry(Object key, Object value){
this.key = key;
this.value = value;
}

public Object getKey(){
return this.key;
}

public Object getValue(){
return this.value;
}
}

// …

Vector entries = new Vector();
entries.add(new Entry(„irgendetwas“, 1));
entries.add(new Entry(„irgendetwas anderes“, 2));

Entry random = entries.elementAt(
Math.round( (float)
(Math.random() * (entries.size()-1 )
)
);

Kann sein, dass ein paar kleinere Fehler drin sind. Hab es nicht ausprobiert. Das Prinzip stimmt aber. :smile:

MfG
[email protected]
http://www.computer-link.de

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin

Hashtable hat ein Funktion „Enumeration
keys()“. Was da rauskommt ist in keiner speziellen Ordnung,
also mehr oder weniger random.

eigentlich meinte ich nur ein paar zufällige Einträge aus der
Hashtabelle, also nicht alle.

Du must ja nicht alle nehmen die aus der Enumeration rauskommen, man kann ja vorher aufhören:

Hashtable hash = new Hashtable();

(… hash füllen …)

Hashtable nur_ein_paar_Elemente_aus_hash = new Hashtable();
Enumeration e = hash.keys();

int groesse_von_hash = hash.size();
int ein_paar = groesse_von_hash/10;  //also 10% der Elemente aus hash

for (int i = 0; i

Moin, moin,

Moin

Jetzt möchte ich
zufällige Einträge aus der Hashtabelle entnehmen. Wie mache
ich das ?

Hashtable hat ein Funktion „Enumeration
keys()“. Was da rauskommt ist in keiner speziellen Ordnung,
also mehr oder weniger random.

Na ja, so ganz richtig ist das nicht. Es ist schon eine Ordnung drauf, nur sobald ein neuer Wert in die Hashtable reinkommt, so wird i.d.R. nicht mehr die alte Reihenfolge über keys() rauskommen.
Zwei unabhängige keys() Aufrufe ohne Änderung der Hashtable liefern aber immer die Key-Elemente in der gleichen Reihenfolge.

Für das obige Problem kann man evtl. auch folgendes nehmen

Hashtable h = ...
Object[] str = h.keySet().toArray();

...
Random rnd = new Random();

final int choosenIndex = rnd.nextInt(str.length);
return (String)str[choosenIndex];

Was die Performance jedoch bei großen Hashtables angeht sollte man sich evtl. aber anschauen (so etwa ab n>100000 und Anzahl der Aufrufe). Aber zum Glück kann man sich ja die Implementierung von

h.keySet().toArray()

im Quelltext anschauen.

Gruß,
Frank

Hi René,

danke für die Antwort.
Das Problem ist, dass ich eine Hashtable mit String als Key und Integer als Wert nehme, weil ich den Wert inkrementieren will, wenn ein String schon in der Hahtable vorhanden ist. Das heisst ich zähle sozusagen die Vorkommen von Strings.
Nun möchte ich per Zufall etwa 60 Strings mit ihrer Häufigkeit herausnehmen. Das Problem dabei ist auch, dass die Hashtable über ein halbes Jahr lang gefüllt wird und dort am Ende ca. 400 000 Einträge stehen. Ich könnte natürlich den KeySet in ein array umwandeln und 60 zufällige Indizes nehmen, aber ich weiss nicht, ob es bei so vielen Einträgen zum Schluss so toll ist.

Grüße,

Tris

Hi Tris,
du könntest ja dir 60 zufällige zahlen von 1 bis 400000 aussuchen. während eines durchlaufes der tabelle zählst du hoch und bei übereinstimmung nimmst du den wert. ist vielleicht nicht super-effizient, aber zufällig.

ich würde die tabelle in mehrere aufteilen. für jeden anfangsbuchstaben eine tabelle. so hast du z.b. 26 kleinere tabellen. schneller wäre es aber nicht unbedingt. aber wenn eine tabelle zu gross wird, dann dauert das rehashen der tabelle nicht so lange. vielleicht brauchst du auch nur eine/einige gleichzeitig im speicher halten.

übrigens habe ich eine auch eine frage zu hash-tabellen gestellt, sie steht weiter oben im brett.

grüsse chris

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]