Description: a set of numbers may be assigned to groups Arr [n] n [seed, limit] li.
For example there is a large fruit basket some small apple, pineapple, durian, requires a similar size as possible into a box, the same type of fruit in claim 2 as far as possible to put a box
A box can hold 20--40 fruit
In this way it can be divided
case 1 : 20 35 40 20 19
case 2: 20 35 40 20 1
This requires it last in equal shares to the other box, a box is now placed before, sharing algorithm depends on the sort of importance and the actual situation.
/// <Summary> /// dynamic grouping algorithm /// </ Summary> /// <typeParam name = "T"> </ typeParam> /// <param name = "Source"> source </ param> /// <param name = "sEED"> seed </ param> /// <param name = "limit"> maximum number of each restriction </ param> /// <param name = "breakFunc"> group function < / param> /// <param name = "flatLimit"> flat quantity </ param> /// <Returns> </ Returns> public static List <List <T>> Group<T>(this List<T> source, int seed, int limit, Func<List<T>, T, bool> breakFunc, FlatGroupType flatType = FlatGroupType.None, int? flatLimit = null) { var res = new List<List<T>>(); while (true) { var buffer = source.Take(20).ToList(); if (buffer.Count == 0) break; var last = buffer.Last(); var inter = source.Except(buffer).ToList().GetEnumerator(); while (true) { inter.MoveNext(); var current = inter.Current; if (current == null || breakFunc(buffer, current) || buffer.Count == 40) { break; } buffer.Add(current); } res.Add(buffer); source = source.Except(buffer).ToList(); buffer = new List<T>(); } if (res.Last().Count < seed) { if (flatLimit == null) { flatLimit = seed; } new FlatGroup(flatType).FlatLast(res, flatLimit.Value); } return res; } public class FlatGroup { private readonly FlatGroupType flatType; public FlatGroup(FlatGroupType flatGroupType) { flatType = flatGroupType; } internal void FlatLast<T>(List<List<T>> source, int flatLimit) { if (source.Count == 1) return; var last = source.Last(); if (last.Count <= flatLimit) { source.Remove(last); Flat(source, last); } } internal void Flat<T>(List<List<T>> source, List<T> toFlat) { if (flatType == FlatGroupType.PushUp) { source.Last().AddRange(toFlat); } } }