Java数组如何限制元素总和为45且元素数量在3到20之间随机
原代码问题排查
- 参数赋值无效:Java为值传递,方法内部执行
cards = new int[45]仅会修改方法内的局部引用,外部传入的数组对象不会被改动,无法拿到生成结果 - 数值生成无约束:每个元素独立随机生成,没有总和限制,必然会出现总和超出45的问题
- 统计逻辑完全反向:初始sum值设为45,还不停累加元素值,完全不符合总和固定为45的要求
- 数组初始化不合理:固定生成45长度的数组,实际仅用到前N个位置,空间浪费且不符合动态长度的需求
实现方案
采用隔板法生成符合要求的数组,逻辑如下:
- 先随机生成3~20之间的元素个数N
- 将总和45看做45个连续的数值,在1~44的间隙中随机选择N-1个不重复的位置插入隔板
- 相邻隔板的差值即为每个数组元素的值,所有元素总和恰好为45,且每个元素都是正整数,符合你的示例要求
修改后代码
推荐实现(返回数组结构,更符合Java编码规范)
import java.util.Arrays; import java.util.Random; public class CardGenerator { public static int[] generateCards() { Random rand = new Random(); // 生成3~20之间的元素个数 int numStacks = rand.nextInt(18) + 3; int[] separators = new int[numStacks + 1]; // 首尾隔板固定 separators[0] = 0; separators[numStacks] = 45; // 生成N-1个不重复的中间隔板 for (int i = 1; i < numStacks; i++) { int sep; boolean isRepeat; do { isRepeat = false; sep = rand.nextInt(44) + 1; // 隔板取值范围为1~44 // 校验重复 for (int j = 0; j < i; j++) { if (separators[j] == sep) { isRepeat = true; break; } } } while (isRepeat); separators[i] = sep; } // 对隔板位置排序 Arrays.sort(separators); // 计算每个元素的数值 int[] cards = new int[numStacks]; for (int i = 0; i < numStacks; i++) { cards[i] = separators[i + 1] - separators[i]; } return cards; } // 测试用例 public static void main(String[] args) { int[] cards = generateCards(); int sum = 0; for (int num : cards) { System.out.print(num + " "); sum += num; } System.out.println("\n总和校验:" + sum); } }
保留原方法签名的实现
如果必须保留你原有的startGame方法结构,可使用以下修改版本,要求传入的数组长度不小于20:
import java.util.Arrays; import java.util.Random; public static void startGame(int[] cards) { if (cards == null || cards.length < 20) { throw new IllegalArgumentException("传入的数组长度不能小于20"); } Random rand = new Random(); int numStacks = rand.nextInt(18) + 3; int[] separators = new int[numStacks + 1]; separators[0] = 0; separators[numStacks] = 45; for (int i = 1; i < numStacks; i++) { int sep; boolean isRepeat; do { isRepeat = false; sep = rand.nextInt(44) + 1; for (int j = 0; j < i; j++) { if (separators[j] == sep) { isRepeat = true; break; } } } while (isRepeat); separators[i] = sep; } Arrays.sort(separators); // 清空数组前N个位置旧值 Arrays.fill(cards, 0, numStacks, 0); int sum = 0; for (int i = 0; i < numStacks; i++) { cards[i] = separators[i + 1] - separators[i]; sum += cards[i]; System.out.println(cards[i]); } System.out.println("总和校验:" + sum); }
内容的提问来源于stack exchange,提问作者David___S__
相关产品推荐
相关产品推荐

