给定一个sorted list
和一个变量n
,我想把list
分解成n
部分,对于n = 3,
,我期望有三个lists
,最后一个取overflow
。
我期望:0,1,2,3,4,5
、6,7,8,9,10,11
、12,13,14,15,16,17
如果list
中的items
的个数不是divisible
乘n
,那么就把溢出的(mod n)
放到最后的list
中。
这不起作用:
static class Program
{
static void Main(string[] args)
{
var input = new List<double>();
for (int k = 0; k < 18; ++k)
{
input.Add(k);
}
var result = input.Split(3);
foreach (var resul in result)
{
foreach (var res in resul)
{
Console.WriteLine(res);
}
}
}
}
static class LinqExtensions
{
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> list, int parts)
{
int i = 0;
var splits = from item in list
group item by i++ % parts into part
select part.AsEnumerable();
return splits;
}
}
3条答案
按热度按时间eeq64g8w1#
我认为您会从Linq的.Chunk()方法中受益。
如果您首先计算有多少部分将包含相等的项目计数,您可以将
list
和yield return
各分块,然后将yield return
分块list
的剩余部分(如果list
不能被n
整除)。正如Enigmativity所指出的,
list
应该具体化为ICollection<T>
以避免可能的多重枚举。具体化可以通过尝试将list
强制转换为ICollection<T>
来获得,如果不成功,则回退到调用list.ToList()
。因此,扩展方法的一个可能实现是:
例如小提琴here。
nbewdwxp2#
我发现你的代码有两个问题。首先,你输出结果的方式,不可能区分值的分组,因为你只是在单独的行上输出每个值。
这个问题可以通过对一组中的每个值使用
Console.Write
来解决,然后在分组完成时添加一个Console.WriteLine()
。这样每组的值都显示在单独的一行中。我们还可以通过获取最大值的长度并将其传递给PadRight
方法来填充这些值,使它们整齐排列:现在,您的结果看起来相当不错,只是我们可以看到数字没有按预期进行分组:
这样做的原因是,我们是按照每个项目除以部分数的余数进行分组的,所以,第一组包含除以
3
后余数为0
的所有数字,第二组包含余数为1
的所有项目,依此类推。要解决这个问题,我们应该用一行中的项数(列数)除项目的索引。
换句话说,
18
项除以3
行将得到每行6
项。使用整数除法,从0
到5
的所有索引在除以6
时将具有余数0
,从6
到11
的所有索引在被6
除时将具有余数1
,并且从x1M17N1x到x1M18N1x的所有索引在被x1M20N1x除时将具有余数x1M19N1x。然而,我们也必须能够处理溢出的数字。一种方法是检查索引是否大于或等于
rows * columns
(即它将在新的一行结束,而不是在最后一行)。如果这是真的,那么我们将它设置为最后一行。我不擅长linq,所以可能有更好的方法来写这个,但是我们可以这样修改我们的扩展方法:
现在我们的结果看起来更好:
2uluyalo3#
这应该可以
因此,每个列表应该(理想情况下)有 x/n 个元素,其中x=〉列表中的元素数& n=〉它必须拆分成的列表数
如果x不能被n整除,那么每个列表都应该有 x/n(向下舍入到最接近的整数)。令该数字为'y'。而最后一个列表应该有 * x-y (n - 1)。令该数字为'z'。
第一个for循环所做的是重复创建一个列表的过程,该列表包含适当数量的元素n次。
if-else代码块是用来检查创建的列表是否是最后一个列表,如果是最后一个列表,则有z个条目,如果不是,则有y个条目。
嵌套的for循环将列表项添加到“子列表”(List)中,然后将其添加到要返回的主列表(List)中。
此解决方案(明显)与您的签名和提供的其他解决方案不同。(可以说)更容易理解,虽然更长。当我过去寻找解决方案时,我过去常常采用能让我确切理解发生了什么的解决方案,但我无法完全理解这个问题的其他解决方案(还没有掌握编程的正确窍门)所以我在下面介绍了我写的一个,以防你最终陷入同样的困境。
如果需要更改,请告诉我。