如何用带种子的随机数生成器洗牌数组?代码问题求助
问题分析与修复:洗牌数组时出现重复元素的原因及解决方法
问题根源
你的代码完全偏离了题目要求的洗牌逻辑:
- 题目要求从已生成的成对数字数组中通过随机索引取值,但你直接用
random.nextInt(numPairs)+1生成随机数字覆盖原数组元素,这相当于凭空生成随机数而非对已有数组洗牌,必然会出现重复(比如多次随机到同一个数字)。 - 你写的
if (board[i] != 0)判断毫无意义:因为你刚把board[i]赋值为1~numPairs的数字,永远不会是0;而且只有在换行时才将当前元素设为0,完全不符合“取到元素后标记为已使用”的规则。
正确实现逻辑
严格遵循题目给定的循环规则:
- 初始化带指定种子的随机数生成器
- 循环直到所有元素都被使用(剩余元素数为0)
- 每次生成数组索引范围内的随机数,而非随机数字
- 检查该索引对应的元素是否未被使用(不为0),若是则打印,并将其设为0标记已使用,同时减少剩余元素计数
修复后的代码
import java.util.Random; import java.util.Scanner; public class LabProgram { public static void main(String[] args) { Scanner scnr = new Scanner(System.in); System.out.println("Please enter the number of elements to be paired."); System.out.println(); int numPairs = scnr.nextInt(); int[] board = new int[numPairs * 2]; // 填充数组:每个数字出现两次,升序排列 int num = 1; for (int i = 0; i < board.length; i+= 2) { board[i] = num; board[i + 1] = num; num++; } // 打印初始数组,每行5个元素 for (int i = 0; i < board.length; i++) { System.out.printf("%4d", board[i]); if ((i + 1) % 5 == 0 || i == board.length - 1) { System.out.println(); } } System.out.println(); System.out.println("Please enter a seed number for testing purposes."); System.out.println(); int seed = scnr.nextInt(); Random random = new Random(seed); // 构造时直接设置种子,更简洁 int remainingElements = board.length; int printCount = 0; // 记录已打印元素数,用于换行控制 while (remainingElements > 0) { // 生成0到数组长度-1之间的随机索引 int randomIndex = random.nextInt(board.length); if (board[randomIndex] != 0) { // 打印元素 System.out.printf("%4d", board[randomIndex]); printCount++; // 标记为已使用 board[randomIndex] = 0; remainingElements--; // 每行打印5个元素时换行 if (printCount % 5 == 0) { System.out.println(); } } } // 最后一行不足5个时补换行(可选,匹配初始打印格式) if (printCount % 5 != 0) { System.out.println(); } } }
测试验证
输入数字对数5、种子22时,运行修复后的代码会输出预期结果:
2 1 1 5 3 4 2 4 3 5
完全符合题目要求的(2 1 1 5 3 4 2 4 3 5)。
内容的提问来源于stack exchange,提问作者pg777
相关产品推荐
相关产品推荐

