Gå til innhold

Algoritme for å hente verdier ut fra array


Anbefalte innlegg

Jeg har støtt på et lite problem og hadde vært evig takknemlig hvis noen kunne hjulpet meg litt!

 

Har deklarert en array. I arrayen ligger det verdier lastet inn fra en tekstfil. Jeg skal plukke ut forskjellige, tilfeldige verdier. Bruker en rnd-funksjon for å få til det. Problemet er at en bestemt verdi kun skal plukkes ut en gang, og ved bruk av rnd-funksjonen har jeg ingen garanti for at ikke den samme verdien blir trukket ut 2 ganger. Jeg tenkte først at jeg bare kunne opprette en ny array og føre verdiene over i den etterhvert som de blir trukket ut, men hvordan får jeg da slettet dem fra den opprinnelige arrayen? Er det eventuelt en mulighet å flytte den uttrukne verdien til bunnen av arrayen?

 

Noen tips? Eller smarte måter å gjøre dette på? :)

Lenke til kommentar
Videoannonse
Annonse

Også mulig med litt Linq-magi:

var rnd = new Random();
var randomized = myList.OrderBy( x => rnd.Next());

 

Sorterings-baserte uttrekk som denne, og Harald's forslag itererer hele samlingen først (eller første gang du trekker et element med Linq), så performance-messig er det ikke bra hvis det er en stor liste og du skal trekke et lite antall elementer. Da kan det være bedre å merke "brukte" elementer, og heller trekke på nytt.

Lenke til kommentar

Også mulig med litt Linq-magi:

var rnd = new Random();
var randomized = myList.OrderBy( x => rnd.Next());

 

Sorterings-baserte uttrekk som denne, og Harald's forslag itererer hele samlingen først (eller første gang du trekker et element med Linq), så performance-messig er det ikke bra hvis det er en stor liste og du skal trekke et lite antall elementer. Da kan det være bedre å merke "brukte" elementer, og heller trekke på nytt.

 

Hvordan kan jeg merke "brukte" elementer? Jeg er forholdsvis ny på VB og programmering, så beklager dumt spørsmål! ;P

Lenke til kommentar

Samme måten, men istedetfor å tilordne et tilfeldig tall, tilordner du en boolsk False verdi som du setter til True idet du bruker verdien. Og så sjekker du om den er True for den neste du skal trekke, for i så fall trekker du en annen.

 

Det du sparer er tiden å sortere pluss litt RAM. Men ikke uvesentlig dette hvis du skal f.eks. trekke ut ti nordmenn (=sortere 5.2 mill folk først)

 

HTH. Beste hilsen Harald

Lenke til kommentar

En shuffle er jo linær (vanligvis iterere over array, swap hvert element med tilfeldig element med høyere index). Det kan gjøres i O(n) tid, og gjøres inkrementelt per element.

 

public static IEnumerable<T> Shuffle<T>(this T[] data)
{
   var rnd = new Random();
   var shuffled = data.ToArray();

   for(int i = 0;i<data.Length;i++)
   {
       var j = rnd.Next(data.Length - i);
       Swap(ref shuffled[i], ref shuffled[j + i]);
       yield return shuffled[i];
   }
}

 

Her kopierer jeg arrayet slik at metoden ikke skal mutere arrayet som sendes inn, utover det lages det kun en random for hver gang noen trekker et element fra Shuffle. Hvis man vil spare minne kan det utelates, men da vil orginale arrayet muteres etterhvert som trekkes elementer.

Endret av MailMan13
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...