zoukankan      html  css  js  c++  java
  • 一个好用的分组算法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);
                    }
                }
    
    
            }
  • 相关阅读:
    mysql视图产生派生表无法优化案例
    根据.frm .ibd文件恢复表
    binlog内容时间乱序问题排查
    mysql官方的测试数据库employees超30万的数据,安装方法介绍
    数据库大量Waiting for table flush 状态SQL问题排查
    mysql搭建从库并配置ssl
    MySQL lOAD DATA详解
    redis eval
    aws-rds for mysql 5.7.34时间点恢复数据
    MySQL 如何处理监听连接的
  • 原文地址:https://www.cnblogs.com/zhuwansu/p/10960079.html
Copyright © 2011-2022 走看看