PHP nasıl bir özyinelemeli fonksiyon orijinal argümanı kaydedebilirim?

3 Cevap php

PHP bir Euler sorun üzerinde çalışıyor değilim. Ben şimdiye kadar bu işlevi vardır:

<?php
$biggest = 0;
$counter = 1;
function test($i){
    global $biggest;
    global $counter;
    if ($i == 1) {
    	echo "I'm done! Took me $biggest steps";
    }
    else {
    	if ($i%2 == 0) {
    		$counter = $counter + 1;
    		if ($counter>$biggest) {
    			$biggest = $counter;
    		}
    		test($i/2);	
    	}
    	else {
    		$counter = $counter + 1;
    		if ($counter>$biggest) {
    			$biggest = $counter;
    		}
    		test(3*$i+1);
    	}
    }
} 

test(13);
?>

Ben çoğunlukla yaladı sorun var, ama ben orijinal girişinde geri almak için görünmüyor olabilir. Soru "Bir numara olduğunda, eğer tek yapmanız bile, n / 2 olsun 3n 1, elde edene kadar 1 döndürür. Başlangıç ​​değerini en verimleri nedir" adımları "Eğer birine olsun önce?" Şu anda adımların sayısını iade ediyorum, ama ben özyineleme olarak $ i sıfırlayarak tutmak, bu yüzden başlangıç ​​# adımların benim $ büyük numarasını verdi ne kaydedemezsiniz.

Nasıl bu sayının takip edebilirsiniz, ama aynı zamanda bu döngünün bir sonraki örneği de yok değil? (Sonunda $ i 1000000 <= 1 ($ i için bu şal, $ i + +) döngü olacak)

Teşekkürler!

3 Cevap

Ortak bir yaklaşım baz durumda olsun sonunda, hala kullanılabilir var ki, her zaman içinde orijinal argümanı geçmektir. Bir ilkel (ve neredeyse tamamen ilgisiz örnek):

<?php

function fact($n) {
    if($n == 1) return 1;
    else return $n * fact($n - 1);
}

?>

Bu PHP faktöryel fonksiyonunun son derece temel bir uygulamasıdır. Şimdi son aşamada mevcut başlangıç ​​değeri var ne sebeple olursa olsun istedim ki: fact($n) o memory_fact($n, $initial) gibi bir şey diyebileceğim bir sarıcı işlev oluşturmak istiyorum:

<?php

function fact($n) {
    return memory_fact($n, $n);
}

function memory_fact($n, $initial) {
    if($n == 1) return 1;
    else return $n * memory_fact($n - 1, $initial);
}

?>

Başladığı yerde bu şekilde, memory_fact her zaman bilir.

Çok kolay, sadece bir parametre olarak etrafında geçmek! İşte bazı python-ish pseudocode bulunuyor:

def func(start, arg):
    if foo(arg):
        return func(start, arg+1)
    else:
        return [start, arg]

Sen küresellerle gerekmez; globallerinin kötülük vardır. test() yararlı bir şeyler dönmeye çalışın. Ayrıca, test() atıkların Yukarıda birçok döngüsü bulacaksınız. Kullanmayı deneyin memoization.

İşte Fibonacci sayıları hesaplamak için bir Memoization örnek:

function fib($n) {
    static $data = array(1, 1);
    if (!isset($data[$n])) {
        $data[$n] = fib($n-1) + fib($n-2);
    }
    return $data[$n];
}

Orada (O'da bir (log n) süresi dahil) Fibonacci sayıları işlemek için diğer zaman-verimli sabit uzay yaklaşımlar, ancak Collatz varsayım biraz yanıltıcıdır olduğunu unutmayın.