Fonksiyon, sonsuz bir döngüye dönüşüyor

3 Cevap php

Ben php yazdım bir fonksiyonu ile ilgili bir sorun var. Gördüğünüz gibi fonksiyon değerleri bir dizi dönmek için kendini kullanır.

    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;
	}
}

En kısa sürede bu değişkenlerin her biri için kendisini çağıran gibi sonsuz bir döngüye dönüşür.

Ne bu neden olur?

3 Cevap

Her zaman iki parça bir özyinelemeli işlevi yazma düşünmek gerekir:

  1. Temel durum - hangi noktada size recursing durdurmak ve bir değer döndüren? (Yani liste boştur)
  2. Özyinelemeli durum - (yani listenin kuyruk gönderme yapmak) nasıl tekrar bir işlev diyorsunuz ve nasıl giriş önceki arama farkı nedir

Bu iki kural tutun sağlanması girdi geçerli olduğunu verilen sonlandırır özyinelemeli fonksiyonun sonuçlanmalıdır.

Burada bir özyinelemeli çözüm değil - ancak Java var :)

    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);
	}
}

Onun basit gerçekten, bunu düşündüğünüz zaman.

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

Son rakamı 0 sonsuz bir döngüye neden olur. Yani onu değiştirmek gerekir

if ($day === 'array')

EDIT

Ben de kodunuzu düzeltmek için özgürlük aldı:

/**
 * @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];
}

Ben belki daha iyi bir çözüm olduğunu önerebilir:

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;
}

Sizin işlevi biten değil neden olarak, emin değilim. Normalde iki ayrı fonksiyon gibi olsa çağrıları ile çalışıyoruz ne yapardım:

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;
        }
}

Bu PHP "array" zaman olmamalıdır gibi bir şey yorumladığı sadece örtmek, işler daha kolay okunur ve yanında daha kararlı hale getirir.