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的影響就凸顯出來了,由于在這個問題上,我和我的同學相差的地方僅僅有那個循環次數不一樣了(公式中的累加肯定是一樣的,不然得出的結果是不一樣且不對的)。所以看來,有些時候須要特別的控制一下程序的循環次數,在算法一樣的情況下,尤其對于多層循環的程序,降低循環次數可以出現意想不到的收益。
總結
以上是生活随笔為你收集整理的for循环中一个不容小觑的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: angular.js前端和后台的数据交换
- 下一篇: 国家能源集团:国内首个电源侧新型电力系统