Равномерное разделение на С#

В С# как равномерно делить 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);
        }

Есть ли простой способ сделать это в С#?

Спасибо

Ответ 1

Чтобы получить мой предложенный результат из 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);
}

Ответ 2

Здесь вы идете:

Func<int, int, IEnumerable<int>> f = (a, b) => 
 Enumerable.Range(0,a/b).Select((n) => a / b + ((a % b) <= n ? 0 : 1))

Удачи, объясняя это в классе, хотя:)

Ответ 3

Поскольку это, кажется, домашнее задание, вот подсказка, а не полный код.

Вы выполняете Math.Ceiling и преобразуете 14.28 в 15.

Ответ 4

Алгоритм - это

  • Разделите 100 на 7, поместите результат в X
  • Получить наивысшее четное число ниже X и поместить его в Y.
  • Умножьте Y на 7 и поместите ответ в Z.
  • Уберите Z от 100.

Ответ - это 6 лотов Y плюс любой результат на шаге 4.

Этот алгоритм может работать только для этого конкретного экземпляра.

Я уверен, что вы можете написать это в С#

Ответ 5

Не уверен, что это именно то, что вам нужно, но я бы подумал, что если вы используете Math.ceiling, вы всегда окажетесь слишком большим. Math.floor будет недооценивать и оставлять вас с разницей, которая может быть добавлена ​​к одной из ваших частей по вашему усмотрению.

Например, с помощью этого метода вы можете получить 7 лотов из 14, предоставляя вам остаток 2. Затем вы можете поместить это 2 в одну из своих частей, давая вам ответ, который вы предложили, или вы можете разделить его равномерно и добавьте две части из 15 (как указано в одном из комментариев)

Ответ 6

Не уверен, почему вы работаете с двойниками, но нуждаетесь в семантике целочисленного деления.

    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 с большей гибкостью,

    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;
    }

Стоит отметить, что двойной пример не может быть численно устойчивым, поскольку определенные входные значения и размеры ковша могут привести к утечке дробных значений.