除以3,用C#函数
本文关键字:函数 除以 | 更新日期: 2023-09-27 18:27:09
我有一个函数,它会返回取决于部分值的int值列表:
private List<int> GetColumn(int total, int column)
{
List<int> retList = new List<int>();
if (total <= 0)
{
return retList;
}
if (column < 0 || column > 2)
{
column = 0;
}
int pageSize = total / 3;
int startIndex = column * pageSize;
int endIndex = column * pageSize + pageSize;
if (endIndex > total)
{
endIndex = total;
}
for (int i = startIndex; i < endIndex; i++)
{
retList.Add(i);
}
return retList;
}
但它是错误的,因为:GetColumn(17,0)
它返回[0,1,2,3,4],但应返回[0,1,3,4,5]
对于GetColumn(17,1)-[6,7,8,9,11]
对于GetColumn(17,2)-[12,13,14,15,16]
对于16,它应该返回:对于GetColumn(16,0)-[0,1,2,3,4,5]
对于GetColumn(16,1)-[6,7,8,9,10]
对于GetColumn(16,2)-[11,12,13,14,15]
我的功能应该改变什么?谢谢
如果这是您所需要的(数字按列增加,但行需要首先填充):
for 16:
0 6 11
1 7 12
2 8 13
3 9 14
4 10 15
5
for 17:
0 6 12
1 7 13
2 8 14
3 9 15
4 10 16
5 11
你需要定义哪一列得到了余数:
int remainder = total % 3;
若余数为1,则只有第一列为6个元素。如果余数是2;第二列是6个元素。您需要根据此计算startIndex和endIndex。
所以;
int pageSize = total / 3;
int remainder = total % 3;
int startIndex = column * pageSize + min(column, remainder);
int endIndex = startIndex + pageSize + (remainder > column ? 1 : 0);
应该起作用。我刚刚测试过,它适用于不同的行数,而不是3。
以下是我如何获得公式的,绘制表格是整理此类算法的好方法:
r: 余数,c:列,ps:页面大小(如上计算)
StartingIndex:
. |r:0 |r:1 |r:2
----------------------
c:0|0 |0 |0
----------------------
c:1|ps |ps+1 |ps+1
----------------------
c:2|ps*2|ps*2+1|ps*2+2
如果扩展行大小4:的表,您可以看到一个模式
StartingIndex:
. |r:0 |r:1 |r:2 |r:3
------------------------------
c:0|0 |0 |0 |0
------------------------------
c:1|ps |ps+1 |ps+1 |ps+1
------------------------------
c:2|ps*2|ps*2+1|ps*2+2|ps*2+2
------------------------------
c:3|ps*3|ps*3+1|ps*3+2|ps*3+3
您添加的值是相关列和剩余的最小值
类似地,对于endIndex,当您为给定的余数vs列构建表时,可以看到所需的列长度。我现在不写了,因为在这里绘制表格花了太多时间,我相信你已经有了这个想法。
整数除法向零四舍五入。因此17/3=5和-17/3=-5
我想你想要的是像这个一样四舍五入到下一个整数
int pageSize = (int)Math.Ceiling(total / 3d);
如果我理解正确,要求是:
If the number is 3n, divide it in 3 groups of n, n and n elements.
If the number is 3n+1, divide it in 3 groups of n+1, n and n elements.
If the number is 3n+2, divide it in 3 groups of n+1, n+1 and n elements.
最好的做法是在代码中明确这一点,并避免任何"聪明"的逻辑。直接拆分可以归结为:
If the number is 3n, the divisions are:
0 .. n-1
n .. 2n-1
2n .. 3n-1
If the number is 3n+1, the divisions are:
0 .. n
n+1 .. 2n
2n+1 .. 3n
If the number is 3n+2, the divisions are:
0 .. n
n+1 .. 2n+1
2n+2 .. 3n+1
在c#中,这将类似于:
public static List<int> Divide3Columns(int total, int column)
{
int startIndex = 0;
int endIndex = 0;
int pageSize = total / 3;
if (total % 3 == 0)
{
startIndex = column * pageSize;
endIndex = (column + 1) * pageSize - 1;
}
if (total % 3 == 1)
{
if (column == 0)
{
startIndex = 0;
endIndex = pageSize; //pageSize + 1 elements;
}
else
{
startIndex = column * pageSize + 1;
endIndex = (column + 1) * pageSize;
}
}
if (total % 3 == 2)
{
if (column == 2)
{
startIndex = 2 * pageSize + 2;
endIndex = 3 * pageSize + 1; //same as total - 1;
}
else
{
startIndex = column * (pageSize + 1);
endIndex = (column + 1) * pageSize + column;
}
}
List<int> result = new List<int>();
for (int i = startIndex; i <= endIndex; i++)
{
result.Add(i);
}
return result;
}
答案假设我们总是分成3列,并且只有3列。如果数字是可变的,那么确定列的逻辑可以被泛化。