【问题标题】:Decreasing Loop Interval by 1 in C/C++在 C/C++ 中将循环间隔减 1
【发布时间】:2016-11-26 21:50:49
【问题描述】:

假设我有 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 变量,用于计算其他一些东西。

我们也换个说法

我有一个名为“循环”的 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

我尝试过模(%)。但问题在于第 12 帧循环为 2,因此 (12 % (5 - 2)) 余数为 0,因此它增加了循环值。 以下几行是在求解器中运行的示例代码。 @loop 默认为 0,@Frame 为当前处理帧号。

int loopint = 5 - @loop;

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

【问题讨论】:

  • C 和 C++ 是不同的语言。选一个。或者也许选择你的代码实际编写的语言,这似乎不是任何一种。
  • 它是用类似于C的VEX(sidefx.com/docs/houdini15.5/vex)编写的。我正在寻找算法。 C 或 C++ 都可以。
  • 你可以忽略变量名前的“@”符号。 Frame 是当前处理的帧,你可以认为它是当前的索引。整数循环 = 0; int loopint = 5 - 循环; if (Frame % loopint == 0) 循环 += 1;
  • 我不明白你的意思。对我来说,所有这些在命名时似乎都是一团糟(除非这些名称可能来自您的实际问题,并且它们与通常的编程上下文无关)。一般来说,我觉得这是一种 XY 问题(参见 Meta SE 的What is the XY problem?)。您能否描述您正在解决的真正问题,而不是 a loop 的次要子部分递减(?)递增(?!) variable 称为 循环?

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


【解决方案1】:

如果我理解正确,那么

#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 你有一个高斯和,它有一个封闭的形式 S = n * (n + 1) / 2 对于 n 项。解决这个问题,我们得到

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

如果您希望在开始时进行较短的拉伸,则向上四舍五入将为我们提供解决方案,即 1、2、2、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));
  }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2022-01-11
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多