一个好用的分组算法2

说明:可以将一组数字分到组 Arr[n] n  [seed,limit]  里。

比如 有一大筐水果 有大有小有苹果,有菠萝,榴莲,要求1大小相似的尽量放到一个框里,要求2同类型的水果尽量放一个框

一个框可以盛 20 - 40 个水果

这样分出来可以是

case 1 : 20 35 40 20 19

case 2: 20 35 40 20  1

这样就需要吧最后一个平摊到其他框,目前是放到前一个框里,分摊算法要看排序的重要程度和实际情况了。

 /// <summary>
        /// 动态分组算法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="seed">种子</param>
        /// <param name="limit">每组最大限制数量</param>
        /// <param name="breakFunc">分组函数</param>
        /// <param name="flatLimit">扁平数量限制</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);
                }
            }


        }
原文地址:https://www.cnblogs.com/zhuwansu/p/10960079.html