如何在Dart中生成4个相加等于指定预设值的随机数
Dart 生成和为固定值的N个随机数
以生成4个和为243的随机数为例,推荐用线段切分法实现,随机性均匀,不会出现数值越界问题,代码可直接运行。
整数版本(默认支持生成含0的非负整数,可调整为正整数)
import 'dart:math'; /// [count] 要生成的随机数数量,[targetSum] 要求的固定总和 List<int> genRandomInts({required int count, required int targetSum}) { final rand = Random(); final cuts = <int>[]; // 生成count-1个切分点 while (cuts.length < count - 1) { final point = rand.nextInt(targetSum + 1); // 👉 如果要求所有数都是正整数(不能为0),放开下面两行注释 // final point = rand.nextInt(targetSum - 1) + 1; // if (cuts.contains(point)) continue; cuts.add(point); } cuts.sort(); final res = <int>[]; int prev = 0; for (final p in cuts) { res.add(p - prev); prev = p; } res.add(targetSum - prev); return res; } void main() { // 测试:生成4个和为243的随机数 final nums = genRandomInts(count: 4, targetSum: 243); print('生成的随机数:$nums'); print('和校验:${nums.reduce((a, b) => a + b)}'); // 固定输出243 }
浮点数版本
如果需要生成小数类型的随机数,用下面的实现即可:
import 'dart:math'; List<double> genRandomDoubles({required int count, required double targetSum}) { final rand = Random(); final cuts = List.generate(count - 1, (_) => rand.nextDouble() * targetSum); cuts.sort(); final res = <double>[]; double prev = 0; for (final p in cuts) { res.add(p - prev); prev = p; } res.add(targetSum - prev); return res; } void main() { final nums = genRandomDoubles(count: 4, targetSum: 243); print('生成的随机数:$nums'); print('和校验:${nums.reduce((a, b) => a + b)}'); }
避坑说明
不建议用「先生成前N-1个随机数,最后一个数用总和减去前面数的和」的实现方式,存在两个明显问题:
- 如果不对前N-1个数的取值范围做限制,很容易出现总和超过目标值,最后一个数为负数的问题
- 就算加了范围限制,最后一个数的随机分布会和前面的数不一致,随机性差
内容的提问来源于stack exchange,提问作者Game
相关产品推荐
相关产品推荐

