2017-08-03 96 views
-1

我有一个递归函数。我想优化它少于10秒。更高的内存使用率不是问题。
在C++中优化递归

目前,在Linux上花费大约85秒,在Mac上花费了三倍。

我无法理解我能以何种方式继续?

这里是代码:

using namespace std; 

double get_wall_time(){ 
    struct timeval time; 
    if (gettimeofday(&time,NULL)){ 
     // Handle error 
     return 0; 
    } 
    return (double)time.tv_sec + (double)time.tv_usec * .000001; 
} 

int fun(long long n) { 

    if (n < 0) { 
     cout << "Please enter valid number"; 
     return 0; 
    } 

    else if (n == 0 || n == 1) 
     return 1; 

    else if (n % 2 == 0) 
     return fun(n/2); 

    else if (n % 2 == 1) 
     return fun(n/2) + fun(n/2 - 1); 

    else 
     return 0; 
} 

int main() { 
    double begin = get_wall_time(); 
    cout << fun(123456789) << std::endl; 
    double end = get_wall_time(); 
    cout << "Time elapsed : " << double(end - begin); 
    return 0; 
} 

编辑:
如果n为偶数,则返回f(n/2)
如果n是奇数,返回f(n/2)+f(n/2-1)

+8

只是为了仔细检查,您是否在优化开启的情况下进行了编译? – NathanOliver

+0

'else if(n%2)'和'else if(n%2 + 1)'。你确定你的意思吗?如果'n'很奇怪,你想'回来玩(n/2)'?第二种情况 - 如果总是存在的话,因为'n'是正数 – Justin

+0

'n%2'或'n%2 + 1'总是成立的,你永远不会到达最后的'else'子句。 – Barmar

回答

1

我会用std::mapmemoize的结果,如所以:

std::map<long long, int>fun_results; 
int fun(long long n) { 
    try { 
     return fun_results.at(n); 
    } catch(const std::out_of_range&) { 

     if (n < 0) { 
      cout << "Please enter valid number"; 
      return 0; 
     } 

     else if (n == 0 || n == 1) 
      return fun_results[n] = 1; 

     else if (n % 2 == 0) 
      return fun_results[n] = fun(n/2); 

     else if (n % 2 == 1) 
      return fun_results[n] = fun(n/2) + fun(n/2 - 1); 

     else 
      return 0; 
    } 
} 

结果:

1332403 
Time elapsed : 0.000710011 
+0

你能给我指导它是如何工作的,为什么它如此之快? – user252514

+1

并不比维基百科关于[dynamic programming]的文章更好(https://en.wikipedia.org/wiki/ Dynamic_programming)和[memoization](https://en.wikipedia.org/wiki/Memoization)。简而言之,您的算法一次又一次地计算相同的中间结果。通过存储部分结果,我们保存了大量的递归调用。 –

+0

谢谢,罗布,这就是我想知道的,关键词搜索和学习就像这里,动态编程。 -ve marking wit霍特给予适当的答案让我沮丧。 :( – user252514