用C / C ++减少循环间隔1

时间:2016-11-26 21:50:49

标签: c++ c algorithm loops for-loop

我们说我有15个元素。我想将它们分组为:

group1 = 1 - 5
group2 = 6 - 9
group3 = 10 - 12
group4 = 13 - 14
group5 = 15

这样我就会在每个组中获得如下元素:

group1 = 5
group2 = 4
group3 = 3
group4 = 2
group5 = 1

正如您所看到的,循环间隔正在减少。

我只拿了15个例子。在实际程序中,它是用户驱动的参数,可以是任何东西(希望有几千个)。

现在我要找的是: 无论group1中的是什么,都应该有变量" loop"值0,group2应该有1,group3应该有2,依此类推......" loop"是一个int变量,用于计算其他一些东西。

让我们换句话说

我有一个名为" loop"的int变量。我想为它分配值,以便: 前n帧循环值0下一个(n -1)帧循环值1然后下一个(n - 2)帧循环值2一直到循环值(n - 1)

我们说我的时间轴上有15帧。

所以n将是5 ====>>>>> (5 + 4 + 3 + 2 + 1 = 15;间隔减少1)

然后

前5帧(1 - 5)循环为0然后接下来4帧(6 - 9)循环为1然后接下来3帧(10 - 12)循环为2然后接下来2帧(13 - 14)循环为3对于最后一帧(15),循环是4。

frames       "loop" value
1 - 5    =>     0
6 - 9    =>     1
10 - 12  =>     2
13 - 14  =>     3
15       =>     4

我尝试使用modulo(%)。但问题是第12帧循环是2所以(12%(5 - 2))余数为0所以它增加循环值。 以下行是在解算器中运行的示例代码。 @loop默认为0,@ Frame是当前处理帧编号。

int loopint = 5 - @loop;

if (@Frame % loopint == 0)
    @loop += 1;

1 个答案:

答案 0 :(得分:2)

如果我理解正确,那么

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[]) {
  int n = atoi(argv[1]);

  for(int i = 1; i <= n; ++i) {
    printf("%d: %f\n", i, ceil((sqrt(8 * (n - i + 1) + 1) - 1) / 2));
  }
}

是C中的实现。

这背后的数学如下:你有1 + 2 + 3 + 4 + 5有一个Gauß和,对于n个项有一个闭合形式S = n *(n + 1)/ 2。解决这个问题,我们得到

n = (sqrt(8 * S + 1) - 1) / 2

如果你想在开始时做短暂的延伸,也就是说1,2,3,3,3,3 ......,那么向上舍入就会给我们提供解决方案。

由于你希望拉伸逐渐变短,我们必须反转顺序,因此S变为(n - S + 1)。因此,那里的公式。

编辑:请注意,除非数据集中的元素数量精确地符合n *(n + 1)/ 2模式,否则在开头或结尾都会有较短的延伸。此实现将不规则拉伸放在开头。如果你最后想要它们,

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, char *argv[]) {
  int n = atoi(argv[1]);

  int n2    = (int) ceil((sqrt(8 * n + 1) - 1) / 2);
  int upper = n2 * (n2 + 1) / 2;

  for(int i = 1; i <= n; ++i) {
    printf("%d: %f\n", i, n2 - ceil((sqrt(8 * (upper - i + 1) + 1) - 1) / 2));
  }
}

做到了。这将计算超出元素数量的下一个数字,然后计算如果你有那么多元素你将拥有的数字。