[php] random functie aanspreken in dezelfde functie

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hi mensen,

ik ben bezig met een simpele functie die random een getal genereert en returned.
Deze functie spreek ik meerdere malen aan.
Indien een random getal al eerder is gekozen moet de functie opnieuw gestart worden totdat een uniek getal naar voren komt.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getRandomSentence() {
        
        $iRandom = mt_rand(0,10));
        echo 'gegenereerd: '.$iRandom.'<br />';

        // Generated number reeds in gebruik
        if (in_array($iRandom, $this->aRandomNumbers)) {
                        // functie opnieuw uitvoeren
            $iRandom = $this->getRandomSentence();
        }
        else {
            $this->aRandomNumbers[] = $iRandom;
            return $iRandom;
        }
        
    }


Zodra een waarde reeds bekend is wordt de functie opnieuw opgestart, echter de dan gevonden waarde wordt niet gereturned.

Kan iemand mij hiermee op weg helpen? Het is me niet helemaal duidelijk hoe dit soort recursieve functies werken.

Thanks!

p.s. het werkt wel als de return buiten de else { } gehaald wordt... Kan iemand mij dit uitleggen?

[ Voor 5% gewijzigd door Verwijderd op 24-08-2010 14:32 ]


Acties:
  • 0 Henk 'm!

  • Luqq
  • Registratie: Juni 2005
  • Laatst online: 19-09 14:23
Probeer eens te bedenken wat er nu gebeurt als $iRandom al in je array zit. $iRandom wordt dan een nieuw getal, en dan? Dan komt hij bij het einde, en gebeurt er niks. Je moet de waardie die de functie dan returnt, ook returnen. Dus return $this->getRandomSentence() should do the trick :)

Acties:
  • 0 Henk 'm!

Verwijderd

Recursie lijkt mij in dit geval niet nodig. Je kunt met een simpele while loop net zolang nummers genereren tot je een unieke hebt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
function getUniqueRandomNumber()
{
    do
    {
        $iRandom = mt_rand(0,10);
    } 
    while( in_array($iRandom, $this->aRandomNumbers) )
    
    $this->aRandomNumbers[] = $iRandom;
    return $iRandom;
}

Maar je functie komt helaas wel in een oneindige loop wanneer er 10 nummers zijn gegenereerd; je zult zelf moeten bedenken hoe je met deze situatie omgaat.

(Trouwens, mocht je de do {} while() loop niet kennen; dit is precies hetzelfde als een normale while() loop, maar de inhoud word minstens 1 keer uitgevoerd, ongeacht of de conditie matcht. Met een normale while() loop zou je in dit geval op 2 plekken een random nummer moeten genereren, dit scheelt weer een regel ;). )

[ Voor 3% gewijzigd door Verwijderd op 24-08-2010 14:39 ]


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Verwijderd schreef op dinsdag 24 augustus 2010 @ 14:29:
p.s. het werkt wel als de return buiten de else { } gehaald wordt... Kan iemand mij dit uitleggen?
Da's toch logisch? :)

Als er nu een getal wordt gegenereerd dat al in de lijst staat wordt $iRandom niet geretourneerd.

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@ Luqq/Codecaster: ja tuurlijk!

ik bekeek de herhalende functie als een los geheel zonder te beseffen dat de output daarvan weer als input geldt van de eerdere functie waar deze opnieuw werd aangesproken.
zucht... tijd voor een koffie pauze.

$Kage: Ik ga er eens naar kijken.. geeft dit veel voordeel t.o.v. recursie?

Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op dinsdag 24 augustus 2010 @ 14:46:
@ Luqq/Codecaster: ja tuurlijk!

ik bekeek de herhalende functie als een los geheel zonder te beseffen dat de output daarvan weer als input geldt van de eerdere functie waar deze opnieuw werd aangesproken.
zucht... tijd voor een koffie pauze.

$Kage: Ik ga er eens naar kijken.. geeft dit veel voordeel t.o.v. recursie?
Nou in jouw geval waarschijnlijk niet, maar naar mijn weten moet er bij een functie aanroep wel meer gebeuren op de achtergrond (nieuwe interne 'stack' maken voor lokale variabelen bijvoorbeeld) dan bij een nieuwe 'ronde' in een while loop. Maar goed, er gebeurd zo weinig in de functie dat het waarschijnlijk niet een te meten verschil oplevert.

Acties:
  • 0 Henk 'm!

  • djexplo
  • Registratie: Oktober 2000
  • Laatst online: 07-07 15:40
Jou huidige implementatie is niet slim. Stel dat je Recursie limiet 500 is, en al veel nummers getrokken zijn crashed jou implementatie af en toe.

Beter is het volgende (permutatie) :
PHP:
1
2
3
4
5
6
7
<?php
$numbers = range(1, 20);
shuffle($numbers);
foreach ($numbers as $number) {
    echo "$number ";
}
?>

[ Voor 8% gewijzigd door djexplo op 24-08-2010 14:58 ]

'if it looks like a duck, walks like a duck and quacks like a duck it's probably a duck'


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
^^ genereer inderdaad een sequence en shuffle die. Dan heb je gegarandeerd een uniek nummer en hoef je niet constant een random getal te trekken.

Als je 1000 "random" getallen uit 0-999 wil trekken ("zonder terugleggen") zit je bij het laatste getal het behoorlijk vaak te proberen, terwijl een stukje logica ervoor zorgt dat het met twee vingers in de neus lukt :)

[ Voor 43% gewijzigd door mithras op 24-08-2010 15:18 ]


Acties:
  • 0 Henk 'm!

  • ajakkes
  • Registratie: Maart 2004
  • Laatst online: 16-05 22:32

ajakkes

👑

Als je dan 10 nummers wil hebben uit een reeks van honderd de laatste 90 "eraf knippen" neem ik aan.

👑

Pagina: 1