rand(1,N)
fakat array(a,b,c,..)
hariç
Bilmiyorum ya da ben kendim uygulamak zorunda yerleşik bir işlevi var zaten (nasıl?)?
UPDATE
Nitelikli çözelti excluded array
boyutunu büyük olup olmadığını altın performans olmalıdır.
Hiçbir işlevi yerleşik, ancak could bunu:
function randWithout($from, $to, array $exceptions) {
sort($exceptions); // lets us use break; in the foreach reliably
$number = rand($from, $to - count($exceptions)); // or mt_rand()
foreach ($exceptions as $exception) {
if ($number >= $exception) {
$number++; // make up for the gap
} else /*if ($number < $exception)*/ {
break;
}
}
return $number;
}
Kafamın üst kapalı, bu yüzden parlatma kullanabilirsiniz - ama en azından varsayımsal olarak bile, sonsuz bir döngü senaryoda sona eremez.
Note: fonksiyon koparsa $exceptions
exhausts sizin aralığı - örneğin randWithout(1, 2, array(1,2))
veya randWithout(1, 2, array(0,1,2,3))
(tabii ki) mantıklı bir şey vermeyecektir çağırıyor, ama bu durumda, iade numarası dışında $from
olacak - {[(6) }] aralığı, o yakalamak kolaydır böylece.
$exceptions
zaten sıralanabilir garanti ise, sort($exceptions);
kaldırılabilir.
Eye-candy, Somewhat minimalistic visualisation of the algorithm.
Ben böyle bir fonksiyon yerleşik var sanmıyorum; muhtemelen bunu kendiniz kod gerekecek.
Bu kod, iki çözüm var:
array_rand
ondan bir değer almak içinTam olarak neye ihtiyacınız bağlı ve neden, bu yaklaşım ilginç bir alternatif olabilir.
$numbers = array_diff(range(1, N), array(a, b, c));
// Either (not a real answer, but could be useful, depending on your circumstances)
shuffle($numbers); // $numbers is now a randomly-sorted array containing all the numbers that interest you
// Or:
$x = $numbers[array_rand($numbers)]; // $x is now a random number selected from the set of numbers you're interested in
Her zaman potansiyel sayı kümesi oluşturmak gerekmez, ama bir kez set üretilmesi ve daha sonra aynı kümesinden rasgele sayı bir demet toplama Yani, bu gitmek için iyi bir yol olabilir.
Ne yapmanız gereken size uzunluğu M = N - #of exceptions
sürekli bir dizi rastgele bir pozisyon almak ve kolayca geri delikleri ile özgün dizi eşlemek böylece atlanan yerlerde bir dizi hesaplamak olduğunu. Bu zaman ve atlanan diziye eşit alanı gerektirecektir. Ben bu yüzden metinsel yarı psudo kod örneği affet toprağa bir delik php bilmiyorum.
i
unsurları olurdu hayal olmayan holey dizideki ilk dizin depolamak.0..M
sayısında bir rasgele sayı, r
seçin.Offset[i] <= r < Offest[i+i]
Bu ikili bir arama ile kolay olduğunu i
gibi Bulr + i
Şimdi size diziler uçları ile başa çıkmak için gereken sadece bir kroki ve işler endeksli form 0 veya 1 ve tüm caz eğer. Eğer gerçekten orijinal anında Offset dizi hesaplayabiliriz akıllı iseniz, olsa bu şekilde biraz daha az açıktır.