如何将数字分成整数,每个都是n的倍数?

时间:2012-03-19 19:26:47

标签: javascript algorithm math

很难为此提出一个简洁的标题。我确信有什么条件可以达到我想要完成的目标,毫无疑问是一种通用的算法来完成我之后的事情 - 我还不知道它们。

我需要将一个数字分成n个,每个都是50的倍数。这个数字本身是50的倍数。这是一个例子: 将5,000除以3,最后得到三个数字,每个数字为50的倍数:

  • 1,650
  • 1700
  • 1650

我也希望分发这些数字,以便它们来回翻转,这里有一个例子,有更多的数字来说明这一点: 将5,000除以7,最后得到7个数字,每个数字为50的倍数:

  • 700
  • 750
  • 700
  • 750
  • 700
  • 700
  • 700

请注意,在上面的示例中,我并不担心额外的50不会在系列中居中,也就是说我不需要这样的事情:

  • 700
  • 700
  • 750< ---注意' 50s'
  • 700
  • 750< ---注意' 50s'
  • 700
  • 700

希望我已经清楚地问到这一点,你明白我想要完成的事情。

更新:这是我正在使用的功能。

var number = 5000;
var n = 7;
var multiple = 50;

var values = getIntDividedIntoMultiple(number, n, multiple)

function getIntDividedIntoMultiple(dividend, divisor, multiple)
{
    var values = [];
    while (dividend> 0 && divisor > 0)
    {
        var a = Math.round(dividend/ divisor / multiple) * multiple;
        dividend -= a;
        divisor--;
        values.push(a);
    }

    return values;
}

7 个答案:

答案 0 :(得分:6)

var number = 5000;
var n = 7;

var values = [];
while (number > 0 && n > 0) {
    var a = Math.floor(number / n / 50) * 50;
    number -= a;
    n--;
    values.push(a);
}  // 700 700 700 700 700 750 750

修改

您可以替换Math.floorMath.ceil以获得所需的结果:

while (number > 0 && n > 0) {
    if (a%2 == 0)
        a = Math.floor(number / n / 50) * 50;
    else
        a = Math.ceil(number / n / 50) * 50;
    number -= a;
    n--;
    values.push(a);
}  // 700 750 700 750 700 700 700

答案 1 :(得分:2)

// i - an integer multiple of k
// k - an integer
// n - a valid array length
// returns an array of length n containing integer multiples of k
// such that the elements sum to i and the array is sorted,
// contains the minimum number of unique elements necessary to
// satisfy the first condition, the elements chosen are the
// closest together that satisfy the first condition.
function f(i, k, n) {
  var minNumber = (((i / k) / n) | 0) * k;
  var maxNumber = minNumber + k;
  var numMax = (i - (minNumber * n)) / k;
  var nums = [];
  for (var i = 0; i < n - numMax; ++i) {
    nums[i] = minNumber;
  }
  for (var i = n - numMax; i < n; ++i) {
    nums[i] = maxNumber;
  }
  return nums;
}

所以你的第二个例子是

f(5000, 50, 7)

产生

[700,700,700,700,700,750,750]

答案 2 :(得分:2)

设a为您的起始编号,k - 您想要分割的部分数量 假设,b = a / n。
现在你想把b分成k个整数部分。

  • 取k个数,每个等于b / k(整数除法)。
  • 将1添加到第一个b%k数字。
  • 将每个数字乘以n。

实施例: a = 5000,n = 50,k = 7 b = 100
开始系列{14,14,14,14,14,14,14}
在前两个整数{15,15,14,14,14,14,14}中加1 乘以50 {750,750,700,700,700,700,700}。

答案 3 :(得分:2)

您的问题与将X分成N整数段的情况相同,这些整数都在彼此之间(在您找到结果后将所有内容乘以50) 。这样做非常简单 - 将所有N个数字设置为Floor(X/N),然后将{1}}添加到X mod N

答案 4 :(得分:2)

我认为你的问题基本上是把一笔钱划分为几乎相等的特定面额的票据。

例如,将10,000美元划分为7个几乎相等的50美元钞票捆绑。

function getBundles(sum, denomination, count, shuffle)
{
  var p = Math.floor(sum / denomination);
  var q = Math.floor(p / count);
  var r = p - q * count;

  console.log(r + " of " + ((q + 1) * denomination)
      + " and " + (count - r) + " of " + (q * denomination));

  var b = new Array(count);
  for (var i = 0; i < count; i++) {
    b[i] = (r > 0 && (!shuffle || Math.random() < .5 || count - i == r)
        ? (--r, q + 1) : q)
      * denomination;
  }

  return b;
}

// Divide 10,000 dollars into 7 near-equal bundles of 50-dollar bills
var bundles = getBundles(10000, 50, 7, true);

console.log("bundles: " + bundles);

输出:

4 of 1450 and 3 of 1400
bundles: 1400,1450,1450,1400,1450,1400,1450

如果最后一个参数shuffletrue,它会在捆绑包之间随机分配额外的金额。

答案 5 :(得分:0)

这是我的看法:

public static void main(String[] args) {
    System.out.println(toList(divide(50, 5000, 3)));
    System.out.println(toList(divide(50, 5000, 7)));
    System.out.println(toList(divide(33, 6600, 7)));
}

private static ArrayList<Integer> toList(int[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>(args.length);
    for (int i : args)
        list.add(i);
    return list;
}

public static int[] divide(int N, int multiplyOfN, int partsCount) {
    if (N <= 0 || multiplyOfN <= N || multiplyOfN % N != 0)
        throw new IllegalArgumentException("Invalid args");

    int factor = multiplyOfN / N;
    if (partsCount > factor)
        throw new IllegalArgumentException("Invalid args");

    int parts[] = new int[partsCount];
    int remainingAdjustments = factor % partsCount;
    int base = ((multiplyOfN / partsCount) / N) * N;

    for (int i = 0; i < partsCount; i ++) {
        parts[i] = (i % 2 == 1 && remainingAdjustments-- > 0) ? base + N : base;
    }

    return parts;
}

答案 6 :(得分:0)

我的算法提供了部分余数的均匀分布:

function splitValue(value, parts, multiplicity)
{
    var result = [];
    var currentSum = 0;
    for (var i = 0; i < parts; i++)
    {
        result[i] = Math.round(value * (i + 1) / parts / multiplicity) * multiple - currentSum;
        currentSum += result[i];
    }
    return result;
}

对于value = 5000,parts = 7,multiplicity = 50则返回

[ 700, 750, 700, 700, 700, 750, 700 ]