我需要在固定的天数内分发剩余的项目。例如说我有197项和75天分发它们。如果我在75天内显示2个项目,那么我有47个项目未显示。如何在75天内均匀分配剩余的47个项目,这样我就可以获得2,3,3,2,3,3,2,2,3等序列,即3个均匀分布在整个展示。这就是我到目前为止所拥有的
const double num = (double)197/75;
double temp = num;
var list = new List<int>();
for (var t = 1; t <= days; t++)
{
var intPart = int.Parse(Math.Truncate(temp).ToString());
list.Add(intPart);
var remainder = num - intPart;
temp = num + remainder;
}
但我最终只显示了187个项目。我错过了10。
答案 0 :(得分:3)
如AlexD所述,原始答案在某些情况下得出的结果并不理想:
int numItems = 197;
int numDays = 75;
var list = new List<int>();
for (int t = 0; t < numDays; t++)
{
int numItemsInDay = ((t+1)*numItems+numDays/2)/numDays - (t*numItems+numDays/2)/numDays;
list.Add(numItemsInDay);
}
这个想法是每个项目进入由itemIndex*numDays/numItems
的舍入值定义的日期,您可以直接计算一天中的项目数,而无需跟踪以前的项目。
另一种方法。
要在numItems
天内尽可能均匀地传播numDays
个项目,您需要将这些日期分为floor(numItems/numDays)
个项目以及ceil(numItems/numDays)
天的跨度。项目,尽可能均匀地传播跨度。因此,可以通过递归减少跨度数的天数来解决问题。
static List<int> Spread(int numDays, int numItems)
{
List<int> result = new List<int>();
if (numDays <= 1)
{
if (numDays == 1)
result.Add(numItems);
return result;
}
int numItemsInDayLower = numItems/numDays;
int numItemsInDayHigher = numItemsInDayLower+1;
int numDaysHigher = numItems - numItemsInDayLower * numDays;
int numDaysLower = numDays-numDaysHigher;
int numSpansLower = numDaysLower > numDaysHigher ? numDaysHigher + 1 : numDaysLower;
int numSpansHigher = numDaysHigher > numDaysLower ? numDaysLower + 1 : numDaysHigher;
bool isStartingFromSpanLower = numDaysLower > numDaysHigher;
List<int> spanLehgthsLower = Spread(numSpansLower, numDaysLower);
List<int> spanLehgthsHigher = Spread(numSpansHigher, numDaysHigher);
for (int iSpan = 0; iSpan < spanLehgthsLower.Count + spanLehgthsHigher.Count; iSpan++)
{
if ((iSpan % 2 == 0) == isStartingFromSpanLower)
{
for (int i = 0; i < spanLehgthsLower[iSpan/2]; i++)
result.Add(numItemsInDayLower);
}
else
{
for (int i = 0; i < spanLehgthsHigher[iSpan/2]; i++)
result.Add(numItemsInDayHigher);
}
}
return result;
}