动态列布局实现:如何调整取整逻辑保证列数计算结果总和恒为12
解决方案
核心采用最大余数法分配列数,既保证比例尽量贴合原始宽度占比,又能强制总列数固定为12,执行逻辑如下:
- 第一步:计算每个shelf对应的列数浮点值,同时拆分出每个值的整数部分和小数部分
- 第二步:累加所有整数部分得到当前已分配列数总和
- 第三步:计算差值 = 12 - 已分配总和,差值就是需要额外多分配1列的名额
- 第四步:把所有shelf按小数部分从大到小排序,给排名前N个(N等于差值)的shelf的整数部分各加1,最终得到的数值就是最终列数
对应你的示例场景验证:
浮点值分别为3.65、4.69、~3.65
整数部分总和为3+4+3=10,差值=12-10=2
小数部分排序:4.69的0.69最大,其次是两个3.65的0.65,因此前2个各加1
最终得到列数为4、5、3,总和=4+5+3=12,完全符合要求
对应实现代码:
// 预计算每个项的浮点列数、整数部分、小数部分,保留原始索引保证输出顺序和输入一致 var colCalculations = Shelves.Select((shelf, index) => new { Index = index, FloatCol = (12.0 * shelf.Width) / SumShelvesWidth, IntPart = (int)Math.Floor((12.0 * shelf.Width) / SumShelvesWidth), DecimalPart = (12.0 * shelf.Width) / SumShelvesWidth - Math.Floor((12.0 * shelf.Width) / SumShelvesWidth) }).ToList(); // 计算需要额外分配的列数(因为用了向下取整,差值必然为非负数) int totalInt = colCalculations.Sum(x => x.IntPart); int diff = 12 - totalInt; // 按小数部分倒序排列,前diff个项加1,其余保留整数部分,最后按原始索引排序输出 var finalCols = colCalculations .OrderByDescending(x => x.DecimalPart) .Take(diff) .Select(x => new {x.Index, AdjustedCol = x.IntPart + 1}) .Concat(colCalculations .OrderByDescending(x => x.DecimalPart) .Skip(diff) .Select(x => new {x.Index, AdjustedCol = x.IntPart}) ) .OrderBy(x => x.Index) .Select(x => x.AdjustedCol) .ToList(); ShelvesCol.AddRange(finalCols);
内容的提问来源于stack exchange,提问作者Henrique Pombo
相关产品推荐
相关产品推荐

