如何将数值拆分为数量不定的随机块?块大小限指定区间
拆分总项数为随机块(已知最小/最大块大小,块数未知)
需求说明
已知总项数totalItems、块的最小尺寸minChunkSize和最大尺寸maxChunkSize,需将总项数拆分为若干随机块,满足:
- 每个块的大小必须在
[minChunkSize, maxChunkSize]区间内 - 拆分后无剩余项数
- 块数在拆分完成前未知,需在生成每一块时确保剩余项数仍能拆出符合要求的块
有效拆分示例(totalItems=15,min=3,max=5):
- 5,5,5
- 3,3,3,3,3
- 5,4,3,3
反例问题:若前三块选3,5,5,剩余项数为2,不符合最小块大小要求,因此第三块最多只能选4,保证剩余3个刚好符合最小块大小。
现有代码问题
你提供的代码逻辑存在漏洞:
- 当检测到
remainingItems - chunkSize < minChunkSize时,直接将chunkSize设为remainingItems,可能导致chunkSize超过maxChunkSize - 强制将
chunkSize设为maxChunkSize又可能让剩余项数小于minChunkSize,无法形成有效块
正确实现思路
每次生成当前块大小时,需计算安全的可选范围:
- 当前块最小不能低于
minChunkSize - 当前块最大不能高于
maxChunkSize,同时必须保证「剩余项数 - 当前块大小」要么为0,要么至少等于minChunkSize(留给后续块)
修正后的C#代码
private List<int> SplitIntoChunks(int totalItems, int minChunkSize, int maxChunkSize) { List<int> chunks = new List<int>(); int remainingItems = totalItems; Random random = new Random(); while (remainingItems > 0) { // 剩余项数本身符合块大小范围,直接作为最后一块 if (remainingItems >= minChunkSize && remainingItems <= maxChunkSize) { chunks.Add(remainingItems); remainingItems = 0; continue; } // 计算当前块的最大可选值:保证选完后剩余项数至少能形成一个有效块 int currentMax = Math.Min(maxChunkSize, remainingItems - minChunkSize); int currentMin = minChunkSize; // 在安全范围内生成随机块大小 int chunkSize = random.Next(currentMin, currentMax + 1); chunks.Add(chunkSize); remainingItems -= chunkSize; } return chunks; }
代码逻辑说明
- 循环处理剩余项数,优先判断剩余项数是否已符合块大小范围,若是则直接加入列表并结束循环
- 计算当前块的最大可选值:确保剩余项数减去当前块大小后,仍能拆出至少一个符合要求的块
- 在
[currentMin, currentMax]范围内生成随机数作为当前块大小,更新剩余项数后继续循环
内容的提问来源于stack exchange,提问作者Ben Mora
相关产品推荐
相关产品推荐

