如何生成总和为指定数值的9个随机整数?
生成总和固定的9个随机整数
要生成9个总和恰好等于目标值的随机整数,同时保证每个数落在0-101范围内,可采用隔板法结合范围校验的方案实现,具体如下:
核心逻辑
- 利用隔板法生成9个非负整数,确保它们的总和严格等于目标值;
- 校验每个数是否在0-101区间内,若存在超出范围的情况,重新生成直到所有数符合要求。
完整实现代码
public static int[] GenerateRandomStats(int targetSum) { // 边界判断:目标值必须在0到909之间(9个数,每个最大101) if (targetSum < 0 || targetSum > 9 * 101) throw new ArgumentOutOfRangeException(nameof(targetSum), "目标值需介于0到909之间"); Random random = new Random(); int[] result = new int[9]; bool isValid = false; while (!isValid) { // 生成8个随机分割点,范围覆盖1到targetSum+8(隔板法的核心逻辑) List<int> splitPoints = new List<int>(); for (int i = 0; i < 8; i++) { splitPoints.Add(random.Next(1, targetSum + 8)); } // 排序分割点并补充首尾边界 splitPoints.Sort(); splitPoints.Insert(0, 0); splitPoints.Add(targetSum + 8); isValid = true; int total = 0; // 计算每个位置的数值 for (int i = 0; i < 9; i++) { result[i] = splitPoints[i + 1] - splitPoints[i] - 1; total += result[i]; // 校验数值是否在合法范围内 if (result[i] < 0 || result[i] > 101) { isValid = false; break; } } // 兜底校验总和是否正确(理论上不会触发) if (isValid && total != targetSum) isValid = false; } return result; }
代码说明
- 边界校验:提前过滤不可能生成的目标值(比如大于909或小于0),避免无效计算;
- 隔板法原理:把目标值拆分为9个部分,通过随机分割点确保各部分总和严格等于目标值;
- 范围校验与重试:若生成的数超出0-101范围,自动重新生成,直到得到符合要求的数组。
简化版(无数值上限限制)
如果不需要限制每个数的最大值,仅要求总和固定,代码可简化为:
public static int[] GenerateFixedSumRandoms(int targetSum) { if (targetSum < 0) throw new ArgumentOutOfRangeException(nameof(targetSum)); Random random = new Random(); List<int> splitPoints = new List<int> { 0 }; // 生成8个随机分割点 for (int i = 0; i < 8; i++) { splitPoints.Add(random.Next(0, targetSum + 1)); } splitPoints.Add(targetSum); splitPoints.Sort(); int[] result = new int[9]; // 计算每个部分的数值 for (int i = 0; i < 9; i++) { result[i] = splitPoints[i + 1] - splitPoints[i]; } return result; }
内容的提问来源于stack exchange,提问作者kayobi
相关产品推荐
相关产品推荐

