PHP에서 복권을위한 6 개의 난수 생성

이 프로그램은 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)$i를 제거 할 수 있습니다. >가 대신 사용되었으므로 연산자를 <=에서 <로 변경해야합니다.

whilefor 루프로 다시 작성할 수 있습니다.

for ($numbers = []; count($numbers) < 6; /* intentionally empty */ ) 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다