En rubyfråga om hur hitta unika slumptal

Permalänk
Medlem

En rubyfråga om hur hitta unika slumptal

Jag har en array som är fylld med instanser av en klass och dessa har en variabel som innehåller ett nummer. Jag fyller på arrayn med nya instanser och behöver då ett nytt slumptal men det får inte vara något av de tal som redan finns. Hur gör man detta enklast?

Permalänk
Medlem

Det kan inte vara en stäng då? För då kommer ju UUID i tanke.

Permalänk
Medlem

ha en static int counter = 0 som ökas med ett i konstruktorn? eller slumptal var det visst. Lägg dom på motsvarande sätt i en lista som söks igenom efter dubletter?

Visa signatur

www.filipsprogram.tk - lite freeware
"Delight, herregud. Talang är bara förnamnet."

Permalänk
Medlem
Skrivet av Tallrot:

Jag har en array som är fylld med instanser av en klass och dessa har en variabel som innehåller ett nummer. Jag fyller på arrayn med nya instanser och behöver då ett nytt slumptal men det får inte vara något av de tal som redan finns. Hur gör man detta enklast?

Om du har en begränsad mängd tal att välja från kan det vara en idé att ha lägga alla möjliga tal i en lista, och sedan plocka ett slumpmässigt valt tal därifrån. Det valda talet tas sedan bort från listan. Listan kan skapas sekventiellt, alltså ordningen 0, 1, 2, ..., eftersom du väljer index slumpmässigt. Detta är mer effektivt än att slumpa ordningen.

Såvida det inte är stor overhead för att lagra heltal så borde talen [0, 65535] ta upp under en megabyte:

$ irb irb(main):001:0> 65535.size * 65536.0 / 1024**2 => 0.5

Om talen inte är tillräckligt begränsade kan en lösning vara att lagra skapade tal i en lista/tabell. För att slippa linjär söktid är en (hash)map troligtvis bäst. När du ska generera ett tal fortsätter du tills du fått fram ett som inte finns i tabellen. I worst case är dock detta väldigt ineffektivt.

Edit: Förtydligande: Första lösningen är bäst med en array-baserad lista, där index-baserad åtkomst sker med konstant tid. Effektiv borttagning ur en array-baserad lista kan göras genom att byta plats på sista elementet och det element som ska tas bort, och sedan ta bort det nya "sista elementet" (alltså det som ska bort). Alltså (pseudokod):

i = rand(0, MAX) list.swap(i, list.size() - 1) list.remove_index(list.size() - 1)

Detta sker troligtvis på konstant tid (beroende på hur Rubys implementation ser ut).

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Medlem

Slumptal är inte unika. Om du vill ha ett unikt tal (ett ID), börja på 0 och öka successivt.

Permalänk
Medlem
Skrivet av You:

Slumptal är inte unika. Om du vill ha ett unikt tal (ett ID), börja på 0 och öka successivt.

Det stämmer att slumptal i sig inte är unika, men man kan ändå vilka ha icke-sekventiella, unika tal.

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Medlem
Skrivet av lajnold:

Det stämmer att slumptal i sig inte är unika, men man kan ändå vilka ha icke-sekventiella, unika tal.

Möjligtvis. Skulle vara intressant att veta varför TS vill ha just "unika slumptal".

Permalänk
Medlem

Vad sägs om att ha en klasspecifik heltalscounter som ökar för varje ny klassinstans och så plussar man på ett slumptal i intervallet [0,1] dessutom. Det borde uppfylla kraven

Visa signatur

www.filipsprogram.tk - lite freeware
"Delight, herregud. Talang är bara förnamnet."

Permalänk
Medlem

Att fylla en array med nummer och sedan plocka slumpvist borde funka. Stort tack för tipset. Med unikt nummer menar jag bara att samma nummer inte får dyka upp två gånger.

Permalänk
Medlem
Skrivet av Tallrot:

Att fylla en array med nummer och sedan plocka slumpvist borde funka. Stort tack för tipset. Med unikt nummer menar jag bara att samma nummer inte får dyka upp två gånger.

Jo, det är så man brukar definiera "unikt". Men varför vill du ha slumpade tal?