PHP生成元素间隔至少1个数字的随机数组问题求助
解决生成至少间隔1个数字的随机数组问题
原代码使用array_rand()直接从连续序列中选数,无法保证选中数字之间至少间隔1个数字。以下提供两种可行的实现方案:
方案一:数学转换法(高效推荐)
核心思路是通过变量转换,把“选不相邻数字”的问题转化为“选普通不重复数字”的问题,避免循环判断,效率更高。
原理
要选3个满足x2 ≥ x1+2、x3 ≥ x2+2的数字,可做如下转换:
- 令
y1 = x1,y2 = x2 - 1,y3 = x3 - 2 - 此时
y1 < y2 < y3,且y3 ≤ puzzle_size - 2(因为x3 ≤ puzzle_size) - 只需从
1到puzzle_size - 2中随机选3个不重复数字,再转换回原数值即可
代码实现
// 根据难度设置puzzle_size $difficulty = 'easy'; // 可选值:easy/medium/hard switch($difficulty) { case 'easy': $puzzle_size = 8; break; case 'medium': $puzzle_size = 20; break; case 'hard': $puzzle_size = 40; break; } $total_numbers_to_display = 3; // 计算转换后的最大可选值 $max_y = $puzzle_size - ($total_numbers_to_display - 1); // 生成转换后的候选数组 $y_candidates = range(1, $max_y); // 随机选3个不重复的y值 $selected_y = array_rand($y_candidates, $total_numbers_to_display); // 排序保证结果递增(可选,根据需求决定) sort($selected_y); // 转换回原数组的目标数字 $yes_array = []; foreach($selected_y as $index => $y) { $yes_array[] = $y + $index; } // 输出结果 print_r($yes_array);
方案二:循环筛选法(直观易懂)
通过每次选中一个数字后,移除该数字及其前后相邻的数字,确保下一次选数不会出现连续情况。
代码实现
// 根据难度设置puzzle_size $difficulty = 'easy'; // 可选值:easy/medium/hard switch($difficulty) { case 'easy': $puzzle_size = 8; break; case 'medium': $puzzle_size = 20; break; case 'hard': $puzzle_size = 40; break; } $total_numbers_to_display = 3; // 初始化候选数组 $remaining_numbers = range(1, $puzzle_size); $yes_array = []; for($i = 0; $i < $total_numbers_to_display; $i++) { // 从剩余候选中随机选一个 $rand_key = array_rand($remaining_numbers); $selected = $remaining_numbers[$rand_key]; $yes_array[] = $selected; // 移除选中数字及其前后相邻数,避免下次选中连续值 $exclude = [$selected - 1, $selected, $selected + 1]; $remaining_numbers = array_filter($remaining_numbers, function($num) use ($exclude) { return !in_array($num, $exclude); }); } // 排序结果(可选) sort($yes_array); // 输出结果 print_r($yes_array);
两种方案都能生成符合要求的数组,其中方案一效率更高,适合较大的puzzle_size;方案二更直观,便于理解逻辑。
内容的提问来源于stack exchange,提问作者Ron Piggott
相关产品推荐
相关产品推荐

