2 Stimmen

Funktion wird zu einer Endlosschleife

Ich habe ein Problem mit einer Funktion, die ich in php geschrieben habe. Wie Sie sehen können, verwendet die Funktion selbst, um ein Array der Werte zurückzugeben.

    public function getRepeat($day = "array")
{
    if ($day == 'array')
    {//Return an array with the repeated days as values
        foreach (array(1,2,3,4,5,6,0) as $value) 
        {
            if ($this->getRepeat($value))
            {
                $returnArray[] = $value;
            }
        }
        return $returnArray;
    }
    else if (in_array($day, array(1,2,3,4,5,6,0) ))
    {
        if ($day == 1)
            return $this->repeat1;
        if ($day == 2)
            return $this->repeat2;
        if ($day == 3)
            return $this->repeat3;
        if ($day == 4)
            return $this->repeat4;
        if ($day == 5)
            return $this->repeat5;
        if ($day == 6)
            return $this->repeat6;
        if ($day == 0)
            return $this->repeat0;
    }
}

Sobald es sich selbst aufruft, um die einzelnen Variablen zu erhalten, wird es zu einer Endlosschleife.

Was ist die Ursache dafür?

5voto

pjp Punkte 16064

Sie müssen immer daran denken, eine rekursive Funktion in zwei Teilen zu schreiben:

  1. Der Basisfall - an welchem Punkt hören Sie auf zu rekursieren und geben einen Wert zurück (d.h. ist die Liste leer)
  2. Der rekursive Fall - wie ruft man eine Funktion erneut auf und wie unterscheidet sich die Eingabe vom vorherigen Aufruf (d.h. sendet man das Ende der Liste)

Wenn man sicherstellt, dass diese beiden Regeln zutreffen, sollte eine rekursive Funktion entstehen, die beendet wird, wenn die Eingabe gültig ist.

Hier ist eine rekursive Lösung - allerdings in Java :)

    public static void main(String[] args) {

    List<Integer> testVals = new ArrayList<Integer>();
    testVals.add(0);
    testVals.add(1);
    testVals.add(2);
    testVals.add(3);
    testVals.add(4);
    testVals.add(5);

    List<Integer> toMatch = new ArrayList<Integer>(testVals);

    List<Integer> matches = new ArrayList<Integer>();

    repeatRec(testVals, matches, toMatch);

    System.out.println("Matches " + matches);
}

public static void repeatRec(List<Integer> toTest, List<Integer> matches, List<Integer> toMatch) {

    if (toTest.isEmpty()) {
        //we are done
        return;
    } else {

        Integer head = toTest.get(0);

        if (toMatch.contains(head)) {
            matches.add(head);

        }

        //could have else here if we're only interested in the first match
        repeatRec(toTest.subList(1, toTest.size()), matches, toMatch);
    }
}

3voto

OIS Punkte 9481

Eigentlich ist es ganz einfach, wenn man darüber nachdenkt.

0 == 'any text which does not start with a number'

Ihre letzte Ziffer 0 wird eine Endlosschleife verursachen. Sie müssen sie also ändern in

if ($day === 'array')

EDIT

Ich habe mir auch die Freiheit genommen, Ihren Code zu korrigieren:

/**
 * @obsolete
 */
public function getRepeat($day = "array")
{
    if ($day === 'array') {
     return $this->getAllRepeat();
}
    return $this->getRepeatByDay($day);

}

public function __construct()
{
    $this->repeat = array_fill(0, 7, '');
}

public function getAllRepeat()
{
    return $this->repeat;
}

public function __get($value) {
    switch ($value) {
        case 'repeat0':
        case 'repeat1':
        case 'repeat2':
        case 'repeat3':
        case 'repeat4':
        case 'repeat5':
        case 'repeat6':
            return $this->getRepeatByDay(intval(substr($value, -1, 1)));
    }
}

public function getRepeatByDay($day)
{
    if (!isset($this->repeat[$day])) {
        return null;
    }
    return $this->repeat[$day];
}

0voto

Matthew Scharley Punkte 121038

Darf ich vorschlagen, dass vielleicht eine bessere Lösung möglich ist?

public function getRepeat($day = "array")
{
    foreach (array(1,2,3,4,5,6,0) as $value) 
    {
        $tmp = "repeat".$value;
        if ($this->$tmp)
        {
            $returnArray[] = $value;
        }
    }
    return $returnArray;
}

Ich bin mir nicht sicher, warum Ihre Funktion nicht beendet wird. Normalerweise würde ich das, was du versuchst, mit zwei getrennten Funktionsaufrufen machen, z. B.:

public function getRepeat()
{
                foreach (array(1,2,3,4,5,6,0) as $value) 
                {
                        if ($this->getRepeat_r($value))
                        {
                                $returnArray[] = $value;
                        }
                }
                return $returnArray;
}
private function getRepeat_r($day)
{
        if (in_array($day, array(1,2,3,4,5,6,0) ))
        {
                if ($day == 1)
                        return $this->repeat1;
                if ($day == 2)
                        return $this->repeat2;
                if ($day == 3)
                        return $this->repeat3;
                if ($day == 4)
                        return $this->repeat4;
                if ($day == 5)
                        return $this->repeat5;
                if ($day == 6)
                        return $this->repeat6;
                if ($day == 0)
                        return $this->repeat0;
        }
}

Das macht die Dinge einfacher zu lesen und ist außerdem stabiler, falls PHP etwas als "array" wenn es nicht sein sollte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X