이 프로그램은 0에서 45 사이의 6 개의 난수를 생성하며 숫자는 반복 할 수 없습니다. 이 코드를 개선 할 수 있습니까?
$numbers = []; $i = 1; while($i <= 6) { $number = mt_rand(0, 45); if(!in_array($number, $numbers)) { array_push($numbers, $number); $i++; } } sort($numbers); echo implode(" - ", $numbers);
답변
알고리즘이 작동합니다. 그러나 반드시 매우 효율적인 것은 아니며 숫자 수가 증가하면 더 자주 충돌합니다.
일반적으로 고유 한 숫자 집합으로 시작하여 임의의 숫자를 추출하는 것이 더 깔끔합니다. 임의의 숫자를 선택하는 대신 해당 숫자를 선택하고 고유성을 테스트합니다.
PHP는 내장 된 셔플 기능이 있기 때문에 비교적 깔끔하게 만듭니다. (기본적으로 동일한 임의 시스템을 사용하여 Fisher-Yates 셔플 을 수행합니다.)
그래서, 고유 한 값의 배열을 가져오고, 섞고, 선택하고, 결과를 정렬합니다.
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
상수 대신 명명 된 변수를 사용하면 무엇을하고 있는지 더 명확하게 알 수 있습니다.
ideone에서 실행중인 항목보기 : https://ideone.com/1Hh0y8
주석
- 45 개 중 6 개의 고유 한 숫자를 생성하는 것은 충돌이 있더라도 45 개 요소 배열을 섞는 것보다 더 많은 난수를 필요로하지 않습니다. 그리고 일반적인 복권에서 6 번과 45 번이 많이 바뀔지는 의심 스럽습니다.
- @ 200_success-동의했습니다. 첫 번째 문장에서 효율성에 대해 언급했지만 알고리즘에 관한 것이지만 진짜 요점은 깔끔함입니다. 그리고 코드의 기능. 위와 같이 2 단계 중첩도 제거되었으며 매직 넘버 선언을 제외하면 ' 이제 코드 4 줄만 있습니다.
답변
count($numbers)
div의 경우 변수 $i
를 제거 할 수 있습니다. >가 대신 사용되었으므로 연산자를 <=
에서 <
로 변경해야합니다.
while
는 for
루프로 다시 작성할 수 있습니다.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )