非减少数字组合(间隔)

时间:2015-04-06 04:21:58

标签: functional-programming numbers combinations intervals

所以我的问题如下:

给定大小为X的数字和A(第一个数字),B(最后一个数字)区间,我必须找到我可以构建的所有不同类型的非递减组合(增加或无效组合)的数量。 / p>

示例:

Input: "2 9 11"

X = 2 | A = 9 | B = 11

输出:8

可能的组合 - >

[9],[9,9],[9,10],[9,11],[10,10],[10,11],[11,11],[10],[11].

现在,如果它是相同的输入,但是使用不同的X,X行= 4,这会改变很多...

[9],[9,9],[9,9,9],[9,9,9,9],[9,9,9,10],[9,9,9,11],[9,9,10,10]...

1 个答案:

答案 0 :(得分:0)

您的问题可以重新制定,以简化为两个参数 X和N = B - A + 1给出从0开始而不是A的序列。

如果你想在每个项目中准确的X数字,那么它很简单重复组合,其等式将是

x_of_n = (N + X - 1)! / ((N - 1)! * X!)

所以对于你的第一个例子,它将是

X = 2
N = 11 - 9 + 1 = 3
x_of_n = 4! / (2! * 2!) = 4*3*2 / 2*2 = 6

为此,您需要将X = 1添加到x_of_n = 3以获得9,这样您就可以获得所需的总数S[0] = N S[1] = S[0] * (N + 1) / 2 S[2] = S[1] * (N + 2) / 3 ... S[X-1] = S[X-2] * (N + X - 1) / X

我不知道所需输出的简单公式,但是当你将所有公式扩展为一个和时,有一个很好的递归序列,你从(N,X-1)计算下一个(N,X)并总结所有元素:

X = 4, N = 3
S[0] = 3
S[1] = 3 * 4 / 2 = 6
S[2] = 6 * 5 / 3 = 10
S[3] = 10 * 6 / 4 = 15
output = sum(S) = 3 + 6 + 10 + 15 = 34

所以对于第二个例子,你给我们

function count(x, a, b) {
  var i,
    n = b - a + 1,
    s = 1,
    total = 0;
  for (i = 0; i < x; i += 1) {
    s *= (n + i) / (i + 1); // beware rounding!
    total += s;
  }
  return total;
}

console.log(count(2, 9, 11)); // 9
console.log(count(4, 9, 11)); // 34

所以你可以在这里试试代码:

int

更新:如果您使用的语言类型为double(JS只有s = s * (n + i) / (i + 1)), 您需要使用*=而不是function count(x, n) { return n < 1 || x < 1 ? 0 : 1 + count(n - 1, x) + count(n, x - 1); } 运算符来避免临时小数和后续舍入问题。

更新2 :对于功能更强大的版本,您可以使用递归定义

n = b - a + 1

其中{{1}}