Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 爆炸清单<;T>;分组_C#_Asp.net Mvc - Fatal编程技术网

C# 爆炸清单<;T>;分组

C# 爆炸清单<;T>;分组,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个扩展,可以将列表分解为多个组,这使得显示内容变得简单。这是分机码 public static List<List<T>> GroupItems<T>(this List<T> items, int totalGroups) { List<List<T>> groups = null; if (items != null) { groups = new List<List&

我有一个扩展,可以将列表分解为多个组,这使得显示内容变得简单。这是分机码

public static List<List<T>> GroupItems<T>(this List<T> items, int totalGroups)
{
    List<List<T>> groups = null;
    if (items != null)
    {
        groups = new List<List<T>>();
        int itemsPerGroup = (int)Math.Ceiling((double)items.Count / totalGroups);
        if (itemsPerGroup > items.Count)
        {
            List<T> group = new List<T>(items);
            groups.Add(group);
        }
        else
        {

            for (int i = 0; i < totalGroups; i++)
            {
                List<T> group = items.Skip(i * itemsPerGroup).Take(itemsPerGroup).ToList();
                groups.Add(group);
            }
        }
    }

    return groups;
}
现在这是错误的,理想情况下我应该

  • 第1组:4个项目
  • 第2组:3个项目
  • 第3组:3个项目
  • 第4组:3个项目
同样,当我试着把它分成6组时,我得到

  • 第1组:3个项目
  • 第2组:3个项目
  • 第3组:3个项目
  • 第4组:3个项目
  • 第5组:1个项目
  • 第6组:0项
你也可以在附件中看到这一点

理想情况下,这应该是

  • 第1组:3个项目
  • 第2组:2个项目
  • 第3组:2个项目
  • 第4组:2个项目
  • 第5组:2个项目
  • 第6组:2个项目

我错过了什么?如何解决此问题?

每次我都会计算每组的项目数

 int itemsPerGroupCount = 0;
 for (int i = 0; i < totalGroups; i++)
        {
            int itemsPerGroup = (int)Math.Ceiling(
                 ((double)items.Count - itemsPerGroupCount) / (totalGroups - i));

            itemsPerGroupCount += itemsPerGroup;

            List<T> group = items.Skip(itemsPerGroupCount).Take(itemsPerGroup).ToList();
            groups.Add(group);
        }
int itemsPerGroupCount=0;
对于(int i=0;i
我会计算每组的物品(地板而不是天花板):

然后我会计算出剩余项目的数量:

int remainingItems = items.Count % totalGroups
然后在你的循环中:

int itemsToSkip = 0;
for (int i = 0; i < totalGroups; i++)
{
    int itemsPerGroupTemp = itemsPerGroup;
    if (remainingItems != 0) {
        itemsPerGroupTemp++;
        remainingitems--;
    }
    List<T> group = items.Skip(itemsToSkip ).Take(itemsPerGroupTemp).ToList();
    groups.Add(group);
    itemsToSkip += itemsPerGroupTemp;
}
int itemsToSkip=0;
对于(int i=0;i
换一种方式怎么样, 假设你有13件物品想要6组
所以取(int)(13/6)并将其落地,这将给你2。现在用相同的组数(6)乘以组大小(2)得到12。你有13个项目,所以你有一个剩余,添加到第一组。应该为您提供一组组组。

如果您将for循环调整为类似的内容

 for (int i = 0; i < totalGroups; i++)
                {
                    List<T> group = items.Skip(i * itemsPerGroup).Take(itemsPerGroup).ToList();
                    groups.Add(group);
                    if(i==0)
                        itemsPerGroup = (int)Math.Ceiling((double)(items.Count - itemsPerGroup  )/ (totalGroups - 1) );
                }
var result = list.Select((v,i)=>new{Value=v,Index=i})
                 .GroupBy(x => x.Index % numberOfGroups)
                 .Select(grp => grp.Select(x => x.Value).ToList())
                 .ToList();
for(int i=0;i
因为你想要每组的平均值和最早的四舍五入值,只要需要,我可以推荐这种算法

public static List<List<T>> GroupItems<T>(this List<T> items, int totalGroups)
    {
        if (items == null || totalGroups == 0) return null;
        var ret = new List<List<T>>();

        var avg = items.Count / totalGroups; //int  rounds towards 0
        var extras = items.Count - (avg * totalGroups);
        for (var i = 0; i < totalGroups; ++i)
            ret.Add(items.Skip((avg * i) + (i < extras ? i : extras)).Take(avg + (i >= extras ? 0 : 1)).ToList());
        return ret;
    }
publicstaticlist-GroupItems(此列表项,int-totalGroups)
{
如果(items==null | | totalGroups==0)返回null;
var ret=新列表();
var avg=items.Count/totalGroups;//整数向0舍入
var extras=项目数-(平均*总组);
对于(变量i=0;i=extras?0:1)).ToList();
返回ret;
}

它的优点是,它很短,可以考虑,并且可以像任何二维算法一样用O(n^2)进行缩放。设计思想是:找到平均值,在平均值之后找到N=缺少的元素,让前N个元素得到一个额外的元素来填补空白。

如果组中项目的顺序不相关,那么您可以通过按组数的索引对Linq进行分组来简单地做到这一点

var result = list.Select((v,i)=>new{Value=v,Index=i})
                 .GroupBy(x => x.Index % numberOfGroups)
                 .Select(grp => grp.Select(x => x.Value).ToList())
                 .ToList();
那么下面

List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
var result =
    list.Select((v, i) => new { Value = v, Index = i })
        .GroupBy(x => x.Index % 6)
        .Select(grp => grp.Select(x => x.Value).ToList())
        .ToList();

int groupNumber = 1;
foreach (var l in result)
{
    Console.WriteLine("Group {0} : {1}", groupNumber++, string.Join(", ", l));
}
List List=新列表{1,2,3,4,5,6,7,8,9,10,11,12,13};
var结果=
list.Select((v,i)=>new{Value=v,Index=i})
.GroupBy(x=>x.索引%6)
.Select(grp=>grp.Select(x=>x.Value).ToList())
.ToList();
int groupNumber=1;
foreach(结果中的var l)
{
WriteLine(“组{0}:{1}”,groupNumber++,string.Join(“,”,l));
}
将产生这些结果

第一组:1,7,13

第2组:2,8

第3组:3,9

第4组:4,10

第5组:5,11

第6组:6,12


我想您应该做的是计算每个bucket的平均项目数量(也称为List),然后将该数量插入每个bucket,然后插入剩余的对象

注意:保持秩序,
可以替换为

例如:

public static List<List<int>> ExpandIntoGroups(this List<int> items, int totalGroups)
{
    List<List<int>> expandedList = null;
    if (items != null)
    {
        expandedList = new List<List<int>>();

        // Get amount of items to insert per list (for example: for 14 items, 4 groups, returns {4, 4, 3, 3}
        int[] itemsToInsertPerGroup = GetItemsToInsertPerGroup(items, totalGroups);

        // Go over each group
        for (int currGroup = 0, itemCount = 0;
             currGroup < itemsToInsertPerGroup.Length;
             currGroup++)
        {
            // add the list for the group
            expandedList.Add(new List<int>());

            // Add as much items as needed 
            for (int i = 0;
                 i < itemsToInsertPerGroup[currGroup] && 
                 itemCount < items.Count;
                 i++, itemCount++)
            {
                expandedList[currGroup].Add(items[itemCount]);
            }
        }
    }

    return expandedList;
}

private static int[] GetItemsToInsertPerGroup(List<int> items, int totalGroups)
{
    // Get average amount of items per list
    int avgItemsPerGroup = (int)(items.Count / totalGroups);

    int[] itemsToInsert = new int[totalGroups];

    // Set each cell to be the average
    for (int i = 0; i < itemsToInsert.Length; i++)
    {
        itemsToInsert[i] = avgItemsPerGroup;
    }

    // get how many items remain after inserting average amount
    int remainingItems = items.Count - avgItemsPerGroup * totalGroups;

    // Increase the amount needed per cell for each remaining item
    for (int i = 0, j = 0;
         i < remainingItems;
         ++i, ++j)
    {
        itemsToInsert[j]++;
    }

    return itemsToInsert;
}

问题是,在移动到下一个铲斗之前,要先将每个铲斗装满。您似乎希望在所有存储桶中均匀分布。
int itemsPerGroup=(int)Math.天花((double)items.Count/totalGroups)基本上我的方法是错误的。。有什么建议可以让它变得更好吗?请用注释检查这个答案,因为这是一个没有什么有趣的算法问题,有简单的解决方案,我建议你自己去做(即使这需要更多的时间)。正如你的名字表明你正在学习编程一样,寻求帮助并不坏,但在这种情况下,我建议你更努力一点,自己解决它……小组中项目的顺序重要吗?也就是说,前x个项目必须在第一组,或者你能把前x个项目分为不同的组吗?我有4组,4+3+3+3,这是正确的。但是,第1组第4项和第2组第1项是相同的。@learning。。。是的,看起来跳过部分有问题。订单与此非常相关。我已经测试了你的建议,如果我给我4组4+3+3项。然而,第1组第4项和第2组第1项是相同的。在这里的所有解决方案中,这起到了保持项目完整的作用。现在,即使我分成4组,我得到的第五组有0个项目。我将在这里选择你的解决方案作为答案。我已删除插入此处的空项。我已经用其他的s测试过了
public static List<List<int>> ExpandIntoGroups(this List<int> items, int totalGroups)
{
    List<List<int>> expandedList = null;
    if (items != null)
    {
        expandedList = new List<List<int>>();

        // Get amount of items to insert per list (for example: for 14 items, 4 groups, returns {4, 4, 3, 3}
        int[] itemsToInsertPerGroup = GetItemsToInsertPerGroup(items, totalGroups);

        // Go over each group
        for (int currGroup = 0, itemCount = 0;
             currGroup < itemsToInsertPerGroup.Length;
             currGroup++)
        {
            // add the list for the group
            expandedList.Add(new List<int>());

            // Add as much items as needed 
            for (int i = 0;
                 i < itemsToInsertPerGroup[currGroup] && 
                 itemCount < items.Count;
                 i++, itemCount++)
            {
                expandedList[currGroup].Add(items[itemCount]);
            }
        }
    }

    return expandedList;
}

private static int[] GetItemsToInsertPerGroup(List<int> items, int totalGroups)
{
    // Get average amount of items per list
    int avgItemsPerGroup = (int)(items.Count / totalGroups);

    int[] itemsToInsert = new int[totalGroups];

    // Set each cell to be the average
    for (int i = 0; i < itemsToInsert.Length; i++)
    {
        itemsToInsert[i] = avgItemsPerGroup;
    }

    // get how many items remain after inserting average amount
    int remainingItems = items.Count - avgItemsPerGroup * totalGroups;

    // Increase the amount needed per cell for each remaining item
    for (int i = 0, j = 0;
         i < remainingItems;
         ++i, ++j)
    {
        itemsToInsert[j]++;
    }

    return itemsToInsert;
}
Total items : 14
Total groups : 4

List 1 has 4 items
List 2 has 4 items
List 3 has 3 items
List 4 has 3 items

List 1 : 1 2 3 4 
List 2 : 5 6 7 8 
List 3 : 9 10 11 
List 4 : 12 13 14