c - 用两个 for 嵌套循环破译 C 函数的用途,一个 int 输入和一个 int 返回

标签 c math

一位来自另一所大学的 friend 带着这个挑战来找我。我无法帮助他,并且因为我无法理解他应该破译的函数的目的而变得相当困扰。有没有人见过这样的事情?

我尝试过可视化数据,但无法真正从图表中得出任何有意义的结论: (蓝色是mistery的返回值,橙色是上次返回值和当前返回值的差值。为了便于阅读,刻度为对数。)

int mistery(int n){
    int i, j, res=0;
    for(i = n / 2; i <= n; i++){
        for(j = 2; j <= n; j *= 2){
          res += n / 2;
        }
    }
    return res;
}

它看起来像是随机代码,但我实际上已经看到它出现的工作表。欢迎任何意见。

谢谢

最佳答案

在内循环的每次迭代中添加到结果变量的增量仅取决于函数参数 n,函数不会修改该参数。因此,结果是增量 (n/2) 与内循环迭代总数(假设不​​溢出)的乘积。

那么有多少次循环迭代呢?首先考虑外循环。如果 i 的下界为 0,则 n 的包含性上界将产生 n+1 次迭代。但是我们跳过了第一个 n/2 迭代 (0 ... (n/2)-1),所以这是 n+1-(n/2)。这里的所有除法都是整数除法,对于整数除法,对于所有 m 都是如此 m = (m/2) + ((m+1)/2).我们可以使用它来将外循环迭代次数重写为 ((n+1)/2) + 1,或 (n+3)/2(仍然使用整数除法)。

现在考虑内循环。索引变量 j 从 2 开始,每次迭代都会加倍,直到超过 n。这会产生等于 n 的以 2 为底的对数的底数的迭代次数。因此,总迭代次数为

(n+3)/2 * floor(log2(n))

(假设当 n 是 2 的幂时我们可以假设一个精确的结果)。那么,合并的结果是

((n+3)/2) * (n/2) * floor(log2(n))

其中除法仍然是整数除法,并且在乘法之前执行。这解释了为什么函数的导数在参数的 2 次幂处出现尖峰:外循环迭代次数在每个点处增加 1。

我们没有任何上下文来猜测函数的用途,我不认为它是一个众所周知的函数,但我们可以谈谈它的属性。例如,

  • 它渐进地增长得比 n2 快,渐近地比 n3 慢。事实上,
  • 它的形式让人想起那些倾向于出现在计算渐近边界中的形式,因此它可能是某些计算所需的内存或时间的估计或边界。还有,
  • 对于 n> 0,它是严格递增的。由于涉及整数除法,这可能不是很清楚,但请注意 nn + 3 具有相反的奇偶校验,因此每当 n 增加 1 时,恰好是 n/2 和 (n+3)/2增加一个,另一个不变(对数项不减)。
  • 如前所述,它在 2 的幂处突然跳跃。这可以根据外循环的迭代次数来查看,或者根据 floor()< 的参与来查看 单方程形式的函数。
  • 函数的多项式部分与从 1 到 n 的整数之和的方程有关。
  • 函数的对数部分与n的二进制表示中的有效位数有关。

关于c - 用两个 for 嵌套循环破译 C 函数的用途,一个 int 输入和一个 int 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54078913/

相关文章:

python - 我试图用 python ctypes 打开一个用 c 编写的 dll 并运行其中的函数,但它是一个字符,而不是字符串

math - 使用 Sympy 对具有三阶多项式分母的有理函数进行拉普拉斯逆变换

java - 为什么 Math#nextUp 不增加 Double.MIN_VALUE?

python - 是否可以使用 solvePnP 找到 4 个角点的实际位置?

c - 在函数中使用结构数组?

c - pic Controller 中如何将字符串转换为int

c - 如何从子进程为父进程设置环境变量?

Java 数学逻辑

c# - C# 中朴素贝叶斯的概率计算

c - C中的生命游戏,如何写入文件?