编写高效代码(2) 空间换时间——我们总是在走,却忘了停留

来源:互联网 发布:五年级上册优化答案 编辑:程序博客网 时间:2024/04/29 10:28
时间和空间的关系,是霍金这种智商的人要研究的东西,我们只需要知道,在编程时,空间是可以换时间的,时间也是可以换空间的。

         李开复在他的自传《世界因你不同》中描述了他小时候在美国学校里的一个故事,老师出了道题:“谁知道1/7等于多少?”小开复马上大声回答:“0.142857”,老师和同学们都惊呼开复是个天才,其实事实情况是,开复以前在台湾时就记下了这个答案。这就是一个典型的以空间(存储)换时间的例子。

        再举一个编程的例子:打印0~40的Fibonacci序列。

Fibonacci序列:

F(n) = 1,              n = 0 或1

F(n) = F(n–1)+F(n–2)    n >1

        代码如下:

[cpp] view plaincopyprint?
  1. int f(int n)  
  2.   
  3. {  
  4.   
  5.    if(n<=1)  
  6.   
  7.    {  
  8.   
  9.        return 1;  
  10.   
  11.    }  
  12.   
  13.    return  f(n-1) + f(n-2);  
  14.   
  15. }  
  16.   
  17. int main()  
  18.   
  19. {  
  20.   
  21.    int result;  
  22.   
  23.    int i;  
  24.   
  25.    for(i=0; i < 40; i++)  
  26.   
  27.    {  
  28.   
  29.        result = f(i);  
  30.   
  31.        printf("%d\n", result);  
  32.   
  33.    }  
  34.   
  35. }  

         使用这段代码,在我的电脑上需要耗费21秒,而使用下面这段代码,则耗时不到1秒。下面的代码使用了一个数组,将F的值缓存起来,这样计算F(n) = F(n–1)+F(n–2)时就不需要递归执行,直接从数组中取值相加即可。可见,空间换时间的效果是多么的明显。

[cpp] view plaincopyprint?
  1. int arr[40];  
  2.   
  3. int f(int n)  
  4.   
  5. {  
  6.   
  7.    int result;  
  8.   
  9.    if(n <= 1)  
  10.   
  11.    {  
  12.   
  13.        result = 1;  
  14.   
  15.    }  
  16.   
  17.    else  
  18.   
  19.    {  
  20.   
  21.        result = arr[n-1] + arr[n-2];  
  22.   
  23.    }  
  24.   
  25.    arr[n] = result;   
  26.   
  27.    return result;  
  28.   
  29. }  
  30.   
  31. int main()  
  32.   
  33. {  
  34.   
  35.    int result;  
  36.   
  37.    int i;  
  38.   
  39.    for(i=0; i < 40; i++)  
  40.   
  41.    {  
  42.   
  43.        result = f(i);  
  44.   
  45.        printf("%d\n", result);  
  46.   
  47.    }  
  48.   
  49. }  

       

         在商业上最成功的空间换时间的例子是Google和百度的搜索引擎算法,当我们提交一个搜索请求时,搜索引擎并不是现场给我们搜索,要在这么短的时间内搜索全球数不尽的网页是不可能的,它只是将已经搜索好的网页呈现给我们。

 

附:Fibonacci其人

         Fibonacci是在越狱中指证John Abruzzi的污点证人,后被Michael发现藏匿地址的那个人吗?

         非也,此Fibonacci是意大利12世纪著名数学家Leonardo Pisano Fibonacci。在他的一本书中,他提出了这么一个有趣的问题:“假定一对兔子在它们出生整整两个月以后可以生一对小兔子,其后每隔一个月又可以再生一对小兔子。假定现在一个笼子里有一对刚生下来的小兔子,请问一年以后笼子里应该有几对兔子?”这个问题的数学建模,就是Fibonacci序列。

 

         

         本文节选自《大话处理器》第6章。

         一台电脑要真正做到优秀,它的硬件和软件是必须紧密联系在一起的。——乔布斯

         作者微博:  weibo.com/muxiqingyang

0 0
原创粉丝点击