Равномерно разделить на C#
В C# как равномерно разделить 100 на 7?
Так что результат будет
- 16
- 14
- 14
- 14
- 14
- 14
- 14
Код ниже неверен, так как все 7 значений установлены на 15 (всего 105).
double [] vals = new double[7];
for (int i = 0; i < vals.Length; i++)
{
vals[i] = Math.Ceiling(100d / vals.Length);
}
Есть ли простой способ сделать это в C#?
Спасибо
6 ответов
Чтобы получить мой предложенный результат 15, 15, 14, 14, 14, 14, 14:
// This doesn't try to cope with negative numbers :)
public static IEnumerable<int> DivideEvenly(int numerator, int denominator)
{
int rem;
int div = Math.DivRem(numerator, denominator, out rem);
for (int i=0; i < denominator; i++)
{
yield return i < rem ? div+1 : div;
}
}
Test:
foreach (int i in DivideEvenly(100, 7))
{
Console.WriteLine(i);
}
Ну вот:
Func<int, int, IEnumerable<int>> f = (a, b) =>
Enumerable.Range(0,a/b).Select((n) => a / b + ((a % b) <= n ? 0 : 1))
Удачи, объясняя это в классе, хотя:)
Поскольку это, кажется, домашнее задание, здесь есть подсказка, а не полный код.
Вы делаете Math.Ceiling, и он конвертирует 14.28 в 15.
Алгоритм такой
- Разделите 100 на 7, поместите результат в X
- Получите наибольшее четное число ниже X и поместите его в Y.
- Умножьте Y на 7 и поместите ответ в Z.
- Убери Z от 100.
Тогда ответом будет 6 лотов Y плюс какой бы ни был результат шага 4.
Этот алгоритм может работать только для этого конкретного экземпляра.
Я уверен, что вы можете написать это в C#
Не уверен, что это именно то, что вам нужно, но я думаю, что если вы используете Math.ceiling, у вас всегда будет слишком большая сумма. Math.floor будет недооценивать и оставлять вас с разницей, которая может быть добавлена к одной из ваших частей, как вы считаете нужным.
Например, с помощью этого метода вы можете получить 7 лотов из 14, получая остаток от 2. Затем вы можете либо сложить эти 2 в одну из ваших частей, давая ответ, который вы предложили, либо разделить его равномерно и добавить get. две части 15 (как предложено в одном из комментариев)
Не уверен, почему вы работаете с двойниками, но хотите семантику целочисленного деления.
double input = 100;
const int Buckets = 7;
double[] vals = new double[Buckets];
for (int i = 0; i < vals.Length; i++)
{
vals[i] = Math.Floor(input / Buckets);
}
double remainder = input % Buckets;
// give all of the remainder to the first value
vals[0] += remainder;
пример для целых с большей гибкостью,
int input = 100;
const int Buckets = 7;
int [] vals = new int[Buckets];
for (int i = 0; i < vals.Length; i++)
{
vals[i] = input / Buckets;
}
int remainder = input % Buckets;
// give all of the remainder to the first value
vals[0] += remainder;
// If instead you wanted to distribute the remainder evenly,
// priority to first
for (int r = 0; r < remainder;r++)
{
vals[r % Buckets] += 1;
}
Стоит отметить, что двойной пример не может быть численно устойчивым, поскольку некоторые входные значения и размеры сегментов могут привести к утечке дробных значений.