首页 > 代码库 > for循环中一个不容小觑的问题
for循环中一个不容小觑的问题
for(int i=1;i<=100;i++)
作为程序员,我们非常喜欢使用这样的for循环。
但是,其中隐含着一个重要的问题。
过多的编程经历可能使我们的思维产生了一些误解,在上面的for循环中,由于我们在以往过多的编程经历中更加关注for循环体中的内容,导致我们几乎忽略了那个小i的存在,它扮演着作为计数器的一个“小角色”,我们忽略了它,殊不知它的“饭量”也是不小的哦~
#include<stdio.h> #include<time.h> int main() { int temp; /********************************/ temp=clock(); for(int i=1;i<=100;i++); printf("%d\n",clock()-temp); /********************************/ temp=clock(); for(int i=1;i<=1000000000;i++); printf("%d\n",clock()-temp); /********************************/ return 0; }
程序运行结果是:
0
3000
这样看来,那个小i所耗掉的运行时间也是非常可观的。一些编程新手认为程序的运行时间是由循环次数决定的,这样说对于上面的那个程序貌似是对的,但是没有说到本质。稍微懂编程的人都能知道,程序的运行时间是由程序的运算次数决定的,明显加减法要比乘除法快。
对于认为运行时间由循环次数决定的想法是错误的,可以看下面的程序:
#include<stdio.h> #include<time.h> int main() { int n,temp; /********************************/ temp=clock(); n=1; for(int i=1;i<=100000000;i++) { n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; n++,n--; } printf("%d\n",clock()-temp); /********************************/ temp=clock(); n=1; for(int i=1;i<=150000000;i++)n++,n--; printf("%d\n",clock()-temp); /********************************/ return 0; }
程序运行结果:
6291
901
前者的循环次数有一亿次,而后者的循环次数有一亿五千万次,但是后者更快,是因为前者的运算次数多。深入分析,前者的加减法运算次数大约是100000000+100000000*20=2100000000即21亿,比较次数(i<=100000000)是一亿次;而后者加减法运算次数是150000000+150000000*2=450000000即4亿5千万次,比较次数(i<=150000000)是一亿五千万次。前者比后者多了16亿5千万次的加减法,后者比前者多了5千万次的比较,根据数据大小的不同可能会有所差异。
无论如何,我们一方面要认识到决定运行时间的因素到底有哪些,另一方面,我们更不能忽视掉for循环中小i的作用和消耗,尤其在小i嵌入一个二层循环中。
我之前做过一道算法题,我的程序要跑4s,而我同学给我优化的程序只要跑不到1s,但是我始终找不到原因,因为推导的公式中累加的次数是一样的,只不过我的循环是n*sqrt(n),而他的是n*lg(n)。我当时只注重了公式中数据的累加,即我只注重了循环体中的内容,忽视掉了小i也有做加法,尤其是套在一个数据量高达五十万的二层循环中,这时候,小i的影响就凸显出来了,因为在这个问题上,我和我的同学相差的地方只有那个循环次数不一样了(公式中的累加肯定是一样的,不然得出的结果是不一样且不正确的)。所以看来,有些时候需要特别的控制一下程序的循环次数,在算法一样的情况下,尤其对于多层循环的程序,减少循环次数能够出现意想不到的收益。