Avatar billede backfire Nybegynder
22. oktober 2004 - 18:51 Der er 15 kommentarer og
1 løsning

array med unikke tilfældige tal

Jeg ønsker at fylde et array med tilfældige tal, men tallene skal være unikke, og jeg har skrevet følgende funktion, men af en eller anden grund går nogle af tallene igen i arrayet en gang imellem, og nu har jeg stirret mig blind på den og kan ikke se fejlen (sikkert
noget i stil med ikke at se skoven for bare træer...)

Håber der er nogen der kan spotte fejlen...

function getRandomNumbers($intNumbersToShow)
  {
    $arrRandomNumber = array();
    $boolFlag = TRUE;
   
    while(count($arrRandomNumber) != $intNumbersToShow)
    {
      $intNumber = (rand()%10);
     
      if($boolFlag)
      {
        $arrRandomNumber[] = $intNumber;
      }
     
      foreach($arrRandomNumber as $RandomNumber)
      {
        if    ($RandomNumber == $intNumber){$boolFlag = FALSE;}
        else  {$boolFlag = TRUE;}
      }
    }
    print_r($arrRandomNumber);
  }
Avatar billede coderdk Praktikant
22. oktober 2004 - 19:20 #1
før
    print_r($arrRandomNumber);
indsæt:
    $arrRandomNumber = array_unique( $arrRandomNumber );
Avatar billede backfire Nybegynder
22. oktober 2004 - 19:27 #2
Med al respekt, så tror jeg ikke du har prøvet det af, for det vil aldrig virke... Har selvfølgelig tænkt på arra_unique, men at fylde et stort array med tilfældige tal, og så bruge array_unique vil sikkert virke, men i 1 ud 10000000 vil det fejle, og det dutter jo ikke hvis koden skal bruges til at køle et atomkraftværk :-)
Avatar billede coderdk Praktikant
22. oktober 2004 - 20:17 #3
Hvad snakker du om? Det er da vist dig der ikke har prøvet det? Selvfølgelig virker det. array_unique returnerer det array du giver den, blot uden dubletter. Den kan du roligt bruge i forbindelse med at drive et atomkraftværk, hvis du blot benytter den korrekt.

Desuden giver dit program ikke særlig meget mening hvis man ser nærmere efter. Jeg kan se du har prøvet at ikke at tilføje dubletter; jeg går ud fra at det er det din $boolFlag er til. Det virker bare ikke. Desuden vil det ikke give mening ved $intNumbersToShow >= 10.

Jeg ville lave noget i stil med:

    function getRandNum( $amount, $maxRand )
    {
        $result = array();
        if ( $amount >= $maxRand ) return range( 1, $maxRand );
        while ( count( $result ) < $amount )
        {
            while ( true )
            {
                $tal = mt_rand( 1, $maxRand );
                if ( !in_array( $tal, $result ) )
                {
                    $result[] = $tal;
                    break;
                }
            }
        }
        return $result;
    }

    print_r( getRandNum( 10, 100 ) );
Avatar billede rednex Nybegynder
22. oktober 2004 - 20:25 #4
Nå, men SKAL koden så bruges til at køle et atomkraftværk ?

Nej, spøg til side. Du kunne jo bruge in_array() til at se om det nye tal eksisterer i forvejen inden du lægger det ind i dit array. Lav evt. en variabel til at tælle hvor mange elementer du har lagt i arrayet og lad din for-løkke checke på den i stedet. Det er hurtigere end at bruge count() i hvert gennemløb.

/Rednex
Avatar billede backfire Nybegynder
22. oktober 2004 - 20:51 #5
Godt ord igen... Jeg gjorde præcis hvad coderdk foreslog, og det virkede ikke!! Rednex forslag derimod holdt vand og følgende virker 100%....

    while($i != 5) 
    { 
      $intNumber = rand(0, 10);
      if(!in_array($intNumber, $arrRandomNumber))
      {
        $i++;
        $arrRandomNumber[] = $intNumber;
      }
    }
Avatar billede rednex Nybegynder
22. oktober 2004 - 21:10 #6
Så må jeg jo hellere lægge et svar :)
Avatar billede coderdk Praktikant
22. oktober 2004 - 21:46 #7
Cut/pastede du min kode? For den virker da.
Avatar billede olebole Juniormester
23. oktober 2004 - 01:55 #8
<ole>

in_array er voldsom ineffektiv til den slags. Det er langt bedre performende at oprette et associativt test-array:

$aTest = array();
while($i != 5) { 
    $intNumber = rand(0, 10);
    if (!aTest($intNumber)) {
        $i++;
        $arrRandomNumber[] = $intNumber;
        $aTest[$intNumber] = 1;
    }
}

/mvh
</bole>
Avatar billede olebole Juniormester
23. oktober 2004 - 01:56 #9
... og så giver mt_rand() i øvrigt bedre tilfældighed end rand()  :)
Avatar billede olebole Juniormester
23. oktober 2004 - 02:00 #10
... der skulle selvfølgelig have stået:
  if (!$aTest($intNumber)) {
Avatar billede olebole Juniormester
23. oktober 2004 - 02:11 #11
*host-host*
  if (!$aTest[$intNumber]) {
Avatar billede rednex Nybegynder
23. oktober 2004 - 02:19 #12
Men ellers går det meget godt, lol ;o) Og du har ret i at det giver bedre performance med et ekstra array.

/Rednex
Avatar billede olebole Juniormester
23. oktober 2004 - 02:48 #13
One should passe på, nicht zu sammenrode viele languages  :)

VISUAL BASIC ... VIG, SATAN ... DU FORPESTER MIT PHP ...!!!  :D
Avatar billede roenving Novice
23. oktober 2004 - 02:54 #14
Eller en effektiv scrambling af et array (her i javascript, for detaljerne i php kender jeg ikke !-)

<script language="javascript" type="text/javascript">
var nums = new Array(),tmp,n;
for(i=0;100>i;i++)nums[i]=i;
for(i=0;100>i;i++){
  n = Math.floor(Math.random()*nums.length);
  tmp = nums[n];
  nums[n] = nums[i];
  nums[i] = tmp;
}
alert(nums);
</script>
Avatar billede backfire Nybegynder
23. oktober 2004 - 17:39 #15
Egentlig spændende diskussion om performance, der er nok ikke nogen tvivl om at olebole's vil give den bedste... det kunne dog forbedres ved ikke at sætte $aTest[$intNumber] = 1 men i stedet til 0x1, da dette ikke vil afsætte plads i ram på serveren til en hel integer, hvis jeg ikke tager helt fejl!

coderdk-> Jeg har ikke afprøvet dit andet svar, men det første gav ikke succes, og i mellemtiden havde rednex jo svaret desværre, men tak for hjælpen alligevel.
Avatar billede coderdk Praktikant
23. oktober 2004 - 19:52 #16
Begge mine svar var nu før rednex, men never mind :P
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester