如何为6个3行9列的表格生成满足列无重复、每行仅5个数字的数据
表格填充列去重约束实现方案
需求说明
已实现6张3行×9列的表格每行预留5个待填充单元格(锁定单元格标记为0),需要新增列维度约束:同一列内填充的数字不可重复。
实现思路
按列维度做数字去重控制,核心逻辑如下:
- 提前确定可填充的数字池,可根据业务需求调整取值范围
- 遍历每一张卡片的每一列,先统计该列下所有待填充的单元格位置
- 为当前列维护一个已使用数字的数组,每次为单元格分配数字时,仅从未使用的数字中随机抽取,分配完成后将该数字标记为已使用
完整实现代码
// 配置项:可根据业务调整填充数字的范围,示例为1-90 $fillNumberRange = range(1, 90); // 初始化所有单元格为0(锁定状态) $cardNumberArray = []; $AllCardGenerate = []; for($card=1;$card<=6;$card++){ $tempCardNumber = []; for($rowIndex=0;$rowIndex<3;$rowIndex++){ for($columnIndex=0;$columnIndex<9;$columnIndex++){ $tempCardNumber[] = 0; $cardNumberArray[$card][$rowIndex][$columnIndex] = 0; } } $AllCardGenerate[$card] = $tempCardNumber; } // 每行生成5个待填充位置(标记为1),对应规则a实现 for($card=1;$card<=6;$card++){ for($rowIndex=0;$rowIndex<3;$rowIndex++){ $zerosGenerate = []; for($columnIndex=0;$columnIndex<9;$columnIndex++){ $generatedIndex = rand(0,8); if(!in_array($generatedIndex, $zerosGenerate) && count($zerosGenerate)<5){ $zerosGenerate[] = $generatedIndex; $cardNumberArray[$card][$rowIndex][$generatedIndex] = 1; }else if(count($zerosGenerate)<5){ $columnIndex--; } } } } // 按列填充数字,实现规则b(同列不重复) for($card=1;$card<=6;$card++){ // 遍历每一列 for($columnIndex=0;$columnIndex<9;$columnIndex++){ // 统计当前列所有待填充的行位置 $toFillRows = []; for($rowIndex=0;$rowIndex<3;$rowIndex++){ if($cardNumberArray[$card][$rowIndex][$columnIndex] == 1){ $toFillRows[] = $rowIndex; } } // 为当前列分配不重复的随机数 $usedNumbers = []; foreach($toFillRows as $rowIndex){ do { $randomNum = $fillNumberRange[array_rand($fillNumberRange)]; } while(in_array($randomNum, $usedNumbers)); // 写入填充值 $cardNumberArray[$card][$rowIndex][$columnIndex] = $randomNum; $usedNumbers[] = $randomNum; } } }
说明
- 可根据业务需求灵活调整
$fillNumberRange的取值范围 - 填充环节优先按列遍历,每列单独维护已使用数字集合,从根源避免同列出现重复值
- 完全兼容原有规则a的实现逻辑,不需要改动已有的待填充位置生成代码
内容的提问来源于stack exchange,提问作者Engineer
相关产品推荐
相关产品推荐

