kostenloser Webspace werbefrei: lima-city


rand() mit Ausnahmen von Zahlen

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    sneppa

    Kostenloser Webspace von sneppa

    sneppa hat kostenlosen Webspace.

    Hallo!
    Ich frage mich heut schon den ganze Tag ob es so eine Funktion wie rand() mit Zahlen gibt, die nicht dabei sein sollen.
    Beispiel

    rand(1,25) aber 3,9,5,19 nicht.

    Wäre nett wenn mir da jemand auf die Sprünge helfen könnte!
    MfG SNEPPA
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Ich hab jetzt ein wenig gesucht, aber Naja.. Gefunden habe ich nichts.

    In dem Fall würde ich mit Arrays arbeiten. Du könntest beispielsweise einen Array mit erlaubten, einen mit unerlaubten Zahlen machen und dann durchzählen lassen uswuswusw..wäre nunmal recht komplex...>_>
  4. cbhp

    Co-Admin Kostenloser Webspace von cbhp

    cbhp hat kostenlosen Webspace.

    Erstelle einfach ein Array, dessen Inhalt so aussieht:

    Index: 0 , Text: 1
    Index: 1 , Text: 2
    Index: 2 , Text: 4
    Index: 3 , Text: 6
    Index: 4 , Text: 7
    Index: 5 , Text: 8

    Dann ermittelst du eine Zufallszahl zwischen 0 und 5 (Indexzahl) und rufst den Wert im Array ab..

    Wie der Code dazu aussieht kann ich dir allerdings nicht sagen..
    falls dich interessiert eine Lösung in VB:
    http://www.lima-city.de/boards.php?mode=thread&id=55879
  5. Autor dieses Themas

    sneppa

    Kostenloser Webspace von sneppa

    sneppa hat kostenlosen Webspace.

    ich hab mir jetzt überlegt:
    ich erstell eben ne Array mit denen Zahlen die nicht benutzt werden dürfen, diese
    werden dann bei der Array mit allen erlaubten Zahlen weggemacht, danach generiere
    ich ein rand() und gebe den Xten Wert aus der Array aus, doch jetzt stell ich mir
    gerade die Frage, wie ich die nicht erlaubten Zahlen aus der anderen Array lösche,
    wie geht das?

    //edit:
    Ich muss mit den unerlaubten Werten anfangen, nicht dass jetzt jemand sagt, fange
    doch gleich mit den erlaubten an...

    Beitrag geaendert: 12.12.2006 13:20:57 von sneppa
  6. Du könntest auc das Try 'n error verfahren verwenden.

    Du erstellst einen Array mit Zahlen, die verboten sind und machst dann einen Rand im angegeben Wertbereich. Dannach lässt du die ausgegebene Zahl mit den verbotenen Abglcihen und so weiter. ALlerdings extrems Resourcenfressend bei großen Arrays usw.


    Die funktion zum löschen...mhh..

    vergleichen ob n e löschung üebrhaupt nötig ist..:
    http://www.creative-edesign.com/php/arrays_vergleichen_uebereinstimmung_ausgeben.php

    Die FUnktion aht mich persönlich jetzt eigentlich itneressiert..und kaum mit dem Thema zusammen..^^"

    http://www.creative-edesign.com/php/array_unique_werte_nur_einmal_ausgeben.php
    ??
    Nützlich?


    Naja..es scheint mir, als müsstest du dafür ne eigene Funktion schreiben.
  7. Autor dieses Themas

    sneppa

    Kostenloser Webspace von sneppa

    sneppa hat kostenlosen Webspace.

    ghostrider91x, danke für die sinnvollen beiträge... http://portofolio.sneppa.de/upload/upload/21bIU-Untitled-2.gif


    adrians ich werd mir mal die seiten durchlesen!
    //edit: das zweite drifft es ziemlich genau auf den punkt, was ich suche :)

    //edit2: das mit dem rand() muss ich auch nichmehr machen da es ja array_rand() gibt :)

    Beitrag geaendert: 12.12.2006 14:17:12 von sneppa
  8. b*****m

    while (($zahl == 5) OR ($zahl == 8)OR ($zahl == 13)) {
    $zahl = rand(1,25);
    }
    echo $zahl;
  9. Brianum..deine Methode ist nicht dynamisch. Aber mit
    while(in_array(forbidden))

    könnte es gehen^^
  10. Hi,

    ich würde es mit einer selebst gebastelten Funktion machen, hier meine Variante:

    function mt_rand_n($min,$max,$n) {
      $da = array_values(array_diff(range($min,$max),$n));
      if (count($da) == 0) return false;
      return $da[mt_rand(0,count($da) - 1)];
    }
    
    // Anwendung:
    echo mt_rand_n(0,10,array(2,3,4,5)); // 2,3,4 und 5 dürfehn nicht gewählt werden
    // Ausgabe: z.B. 6


    Viel Spass :biggrin:.

    mfg,
    hr

    Beitrag geaendert: 12.12.2006 17:49:25 von heavyraptor
  11. adrians schrieb:
    Brianum..deine Methode ist nicht dynamisch. Aber mit
    while(in_array(forbidden))

    könnte es gehen^^


    Dem Stimme ich zu und zwar so:

    while(!in_array(($rand = rand(0,10)),$forbidden))
    {
    echo $rand;
    }
  12. Hi,


    adrians schrieb:
    Brianum..deine Methode ist nicht dynamisch. Aber mit
    while(in_array(forbidden))

    könnte es gehen^^


    Dem Stimme ich zu und zwar so:

    while(!in_array(($rand = rand(0,10)),$forbidden))
    {
    echo $rand;
    }


    Dies Funktioniert gar nicht, da beim ersten false die While-Schleife einfach abgebrochen wird ... verwendet besser meine Funktion die das ganze schneller und richtig erledigt.

    mfg,
    hr

    Beitrag geaendert: 12.12.2006 18:22:15 von heavyraptor
  13. while(!in_array(($rand = rand(0,10)),$forbidden))
    {
    }

    echo $rand;


    Funktioniert auch wunderbarst. *gähn*

  14. while(!in_array(($rand = rand(0,10)),$forbidden))
    {
    }

    echo $rand;


    Funktioniert auch wunderbarst. *gähn*


    Das ! muss weg, sonst geht es nicht.

    mfg,
    hr
  15. Hier mal ein Skript von mir. :D
    <?php
      function filter($var){
        $filter = array(3, 9, 5, 19);
        return (in_array($var, $filter,true) ? false : $var);
      }
      $numbers = range(1, 25);
      $numbers = array_filter($numbers,'filter');
      shuffle($numbers);
      $random = $numbers[rand(0, count($numbers)-1)];
    ?>


    http://www.php.net/manual/de/function.range.php
    http://www.php.net/manual/de/function.array-filter.php
    http://www.php.net/manual/de/function.shuffle.php

    Edit:
    OK, die Variante von hr ist eleganter, schneller und besser. Ich könnte mich selbs ohrfeigen, dass ich array_diff() gar nicht beachtet habe. Naja, was soll's.^^

    Trotzdem habe ich einfach mal das Skript von hr "gepimpt".
    function mt_rand_n($min,$max,$n) {
      $diff = array_values(array_diff(range($min,$max),$n));
      return count($diff) == 0 ? false : $diff[mt_rand(0,count($diff) - 1)];
    }


    Beitrag geaendert: 12.12.2006 19:27:08 von i-spacke
  16. Hi,


    Hier mal ein Skript von mir. :D
    <?php
      function filter($var){
        $filter = array(3, 9, 5, 19);
        return (in_array($var, $filter,true) ? false : $var);
      }
      $numbers = range(1, 25);
      $numbers = array_filter($numbers,'filter');
      shuffle($numbers);
      $random = $numbers[rand(0, count($numbers)-1)];
    ?>


    http://www.php.net/manual/de/function.range.php
    http://www.php.net/manual/de/function.array-filter.php
    http://www.php.net/manual/de/function.shuffle.php

    Edit:
    OK, die Variante von hr ist eleganter, schneller und besser. Ich könnte mich selbs ohrfeigen, dass ich array_diff() gar nicht beachtet habe. Naja, was soll's.^^

    Trotzdem habe ich einfach mal das Skript von hr "gepimpt".
    function mt_rand_n($min,$max,$n) {
      $diff = array_values(array_diff(range($min,$max),$n));
      return count($diff) == 0 ? false : $diff[mt_rand(0,count($diff) - 1)];
    }


    Beitrag geaendert: 12.12.2006 19:27:08 von i-spacke


    Nicht schlecht :biggrin:, deine Variante ist auch ganz ok, aber wie du gesagt hast, ist meine noch ein bischen eleganter :biggrin: (danke :P).
    Meine von dir gepimte Funktion ist natürlich die Beste!

    Also, hier ist die Offizielle Zufallszahl-aber-nicht-die-von-einem-Array-Funktion :biggrin::
    function mt_rand_n($min,$max,$n) {
      $diff = array_values(array_diff(range($min,$max),$n));
      return count($diff) == 0 ? false : $diff[mt_rand(0,count($diff) - 1)];
    }


    mfg,
    hr

    Beitrag geaendert: 12.12.2006 19:40:27 von heavyraptor
  17. Meins kann man auch noch kürzen und man müsste mal einen Benchmark machen, welches Skipt schneller ist.^^
    <?php
      $numbers = array_values(array_filter(range(1, 25),create_function('$var','return (in_array($var, array(3, 9, 5, 19),true) ? false : $var);')));
      $random  = $numbers[rand(0, count($numbers)-1)];
    ?>


    Das ganze als Funktion gestrickt:
    <?php
      function rand_n($min,$max,$n){
        $numbers = array_values(array_filter(range($min, $max),create_function('$var','return (in_array($var, (array)$n, true) ? false : $var);')));
        return $numbers[rand(0, count($numbers)-1)];
      }
      //Beispiel:
      //print rand_n(1,25,array(3,4,5));
    ?>


    Die Version ist doch auch nicht schlecht oder? :D

  18. Meins kann man auch noch kürzen und man müsste mal einen Benchmark machen, welches Skipt schneller ist.^^
    <?php
      $numbers = array_values(array_filter(range(1, 25),create_function('$var','return (in_array($var, array(3, 9, 5, 19),true) ? false : $var);')));
      $random  = $numbers[rand(0, count($numbers)-1)];
    ?>


    Das ganze als Funktion gestrickt:
    <?php
      function rand_n($min,$max,$n){
        $numbers = array_values(array_filter(range($min, $max),create_function('$var','return (in_array($var, (array)$n, true) ? false : $var);')));
        return $numbers[rand(0, count($numbers)-1)];
      }
      //Beispiel:
      //print rand_n(1,25,array(3,4,5));
    ?>


    Die Version ist doch auch nicht schlecht oder? :D


    Hi,

    gute idee mit der Benchmark, ich mach das mal :biggrin::biggrin:.
    Und ja, deine neue VErsion ist auch gut, aber mal sehen, welches schnelelr ist! :biggrin:

    EDIT:
    Spacke, deine Funktion funktioniert gar nicht! :biggrin:
    Da ist ein Fehler in der create_function-Funktion.

    mfg,
    hr

    Beitrag geaendert: 12.12.2006 20:38:30 von heavyraptor
  19. Stimmt, da hatte ich wohl einen kleinen Denkfehler drin. Ich kenne mich mit create_function() auch noch nicht so gut aus.

    Hier die gemeinsam verbesserte Version, die keine Warnungen mehr ausspuckt und auch richtig funktioniert. :D

    <?php
      function rand_n($min,$max,$n) { 
        $numbers = array_values(array_filter(range($min, $max),create_function('$var','return (in_array($var, array('.implode(',',(array)$n).'), true) ? false : $var);'))); 
        return $numbers[rand(0, count($numbers)-1)]; 
      }
    ?>
  20. Hi,

    also, ich habe die Geschindigkeiten der beiden Funktionen gemessen.
    Das Resultat:
    rand_n(): 0.0002411009
    mt_rand_n(): 0.0001652344

    Interpretiertes Resultat:
    Heavyraptor gewinnt!! :biggrin:
    (Spackes Funktion ist aber auch geil :P)

    Dafür habe ich folgendes Script benutzt:
    error_reporting(E_ALL);
    
    header('Content-type: text/plain');
    
    function rand_n($min,$max,$n) {
      $numbers = array_values(array_filter(range($min, $max),create_function('$var','return (in_array($var, array(' . implode(',',(array)$n) . '), true) ? false : $var);')));
      return $numbers[rand(0, count($numbers)-1)];
    }
    
    function mt_rand_n($min,$max,$n) {
      $diff = array_values(array_diff(range($min,$max),(array) $n));
      return count($diff) == 0 ? false : $diff[mt_rand(0,count($diff) - 1)];
    }
    
    $min = 0;
    $max = 20;
    $disallowed = array(1,7,8,10,12,13,14,19);
    
    $m1 = array();
    $m2 = array();
    
    // Init
    for ($i = 0; $i < 10; $i++)
      microtime();
    
    for ($i = 0; $i < 10000; $i++) {
      $s = microtime(true);
      $foo = mt_rand_n($min,$max,$disallowed);
      $m2[] = microtime(true) - $s;
    }
    
    for ($i = 0; $i < 10000; $i++) {
      $s = microtime(true);
      $foo = rand_n($min,$max,$disallowed);
      $m1[] = microtime(true) - $s;
    }
    
    $m1 = array_sum($m1) / count($m1);
    $m2 = array_sum($m2) / count($m2);
    
    echo "rand_n():    " . number_format($m1,10) . "\n";
    echo "mt_rand_n(): " . number_format($m2,10) . "";


    mfg,
    hr

    Beitrag geaendert: 12.12.2006 20:59:09 von heavyraptor
  21. Autor dieses Themas

    sneppa

    Kostenloser Webspace von sneppa

    sneppa hat kostenlosen Webspace.

    *gg* ist aber ziemliches OT, meine Frage ist ja schon lange beantwortet ;)
    Schreibe auch gerade den Script, falls ich nochmal ne frage haben sollte, schreib ich sie hier, ich glaube aber eher nicht!
  22. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!