在C中优化嵌套循环

时间:2017-01-09 05:02:40

标签: c for-loop optimization

我有一个嵌套循环来查找4和4组中1和x之间所有可能的数字组合,其中a< b< c< d。

调用方法,因为发现每个组对这些数字的总和进行简单的等效性测试。

循环确实起作用并产生预期的输出(这个特定的x的1组数字),然而找到这个答案需要12秒以上,而另外〜5来测试剩余的可能性,这绝对是不好的,考虑到x值是< 1000。

我尝试让外循环迭代a&lt; x - 3次,b循环b <1。 x - 2次,低至d <1。 x次没有显着差异。

  

更改此循环有什么更好的方法?

for (a = 1; a < x; a++) {
    for (b = a + 1; b < x; b++) {
        for (c = b + 1; c < x; c++) {
            for (d = c + 1; d < x; d++) {
                check(a, b, c, d);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

如此深层次的嵌套,你可以引入的任何早期退出 - 特别是在外环 - 可以获得巨大收益。

例如,您写道check正在测试a + b + c + d == x && a * b * c * d == x - 这样您就可以计算中间和和产品,并在遇到数字时中断,这样可以选择以后的数字。

一个例子:

for (a = 1; a < x; a++) {
  for (b = a + 1; b < x; b++) {
    int sumAB = a + b;
    if (sumAB + sumAB > x) break;
    int prodAB = a * b;
    if (prodAB * prodAB > x) break;
    for (c = b + 1; c < x; c++) {
      int sumABC = sumAB + c;
      if (sumABC + c > x) break;
      int prodABC = prodAB * c;
      if (prodABC * c > x) break;
      for (d = c + 1; d < x; d++) {
        int sumABCD = sumABC + d;
        if (sumABCD > x) break;
        if (sumABCD != x) continue;
        int prodABCD = prodABC * d;
        if (prodABCD > x) break;
        if (prodABCD != x) continue;
        printf("%d, %d, %d, %d\n", a, b, c, d);
      }
    }
  }
}

这只是一个示例 - 您可以进一步约束所有检查(例如,将第一次检查设为sumAB + sumAB + 3 > x)。关键是要关注早期退出。

我为每个循环添加了一个计数器,计算它输入的次数,并尝试了你的版本和我的版本,x = 100.我的版本的循环条目少了几个数量级:

没有提前退出:99,4851,156849,3764376
早期退出:99,4851,1122,848