通常,实现逻辑的最简单方法是使用模运算符 %。熟悉这个算子;它在有帮助的情况下非常有用。有很多方法可以编写实际代码来分配字母,使用数组或不使用数组等,但这个简短的表达式应该给你一个想法:
"ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(letter) % partitionCount
该表达式给出了存放大写字母的分区的从零开始的索引。该字符串只是为了方便而显示,但可以是数组或其他表示字母的方式。您可以遍历字母表,使用与上述类似的逻辑来选择存放每个字母的位置。由你决定将逻辑放在哪里:在循环中、方法中等。
模运算没有什么神奇之处。它只是在达到可用数字集的末尾后“环绕”。我们都遇到过的一个简单的上下文是除法。% 运算符本质上只是给出除法余数。现在您了解了 % 运算符在做什么,您可以轻松地编写自己的代码来用任何语言做同样的事情。
把这一切放在一起,你可以编写一个像这样的实用程序、类或扩展方法——注意 % 来计算余数,并且那个简单的整数除法会丢弃它:
/// <summary>
/// Returns partition sized which are as close as possible to equal while using the indicated total size available, with any extra distributed to the front
/// </summary>
/// <param name="totalSize">The total number of elements to partition</param>
/// <param name="partitionCount">The number of partitions to size</param>
/// <param name="remainderAtFront">If true, any remainder will be distributed linearly starting at the beginning; if false, backwards from the end</param>
/// <returns>An int[] containing the partition sizes</returns>
public static int[] GetEqualizedPartitionSizes(int totalSize, int partitionCount, bool remainderAtFront = true)
{
if (totalSize < 1)
throw new ArgumentException("Cannot partition a non-positive number (" + totalSize + ")");
else if (partitionCount < 1)
throw new ArgumentException("Invalid partition count (" + partitionCount + ")");
else if (totalSize < partitionCount)
throw new ArgumentException("Cannot partition " + totalSize + " elements into " + partitionCount + " partitions");
int[] partitionSizes = new int[partitionCount];
int basePartitionSize = totalSize / partitionCount;
int remainder = totalSize % partitionCount;
int remainderPartitionSize = basePartitionSize + 1;
int x;
if (remainderAtFront)
{
for (x = 0; x < remainder; x++)
partitionSizes[x] = remainderPartitionSize;
for (x = remainder; x < partitionCount; x++)
partitionSizes[x] = basePartitionSize;
}
else
{
for (x = 0; x < partitionCount - remainder; x++)
partitionSizes[x] = basePartitionSize;
for (x = partitionCount - remainder; x < partitionCount; x++)
partitionSizes[x] = remainderPartitionSize;
}
return partitionSizes;
}