c++ - 指数递归与迭代的效率

标签 c++ performance recursion iteration

所以我正在尝试实现一种更有效的计算 2^n 的方法。

我知道您可以将它拆分为 O(logn) 并且使用递归很容易做到。你一直除以 2,然后在它为奇数(或类似的东西)时乘以较低的幂。问题是我手写了乘法,因为它适用于大数。所以它需要返回多个参数。

我能想到的一个解决方案是制作一对包含所有需要的信息。除此之外,尽管我试图弄清楚如何使用迭代来编写它。我能看到的唯一方法是使用某种数据结构,然后循环将 n 除以 2,并在 n 为奇数时存储该值。然后编写一个 for 循环并在每次迭代时检查该值是否包含在数据结构中。在我看来,这似乎是一项成本相对较高的操作。

它是否有可能最终比递归版本效率低?

我这样做是因为:

  1. 我无法让 gnp 工作。
  2. 我认为我正在通过编写大数类(class)并使用它来学习。

最佳答案

如果您要处理大数字,而不是重新发明轮子,您可能应该看看 GNU MP Bignum Library .

关于递归与迭代的问题,答案是你总是可以把它们写成等价的;一个递归函数,它只将自己称为 tail call与 while 循环一样高效(前提是您的编译器支持尾调用优化,但最常见的编译器支持)。例如,您描述的快速求幂函数的尾递归版本是(伪代码):

function fastExp(base, exponent, accumulator) {
  if(exponent == 0) {
    return accumulator;
  } else if(exponent % 2 == 0) {
    return fastExp(base * base, exponent/2, accumulator);
  } else {
    return fastExp(base, exponent-1, base * accumulator); 
  }
}

将此递归函数视为一个循环,其中循环条件为 exponent != 0,递归调用就像是 goto 到循环的开头. (顺便说一句,你需要在开始时用accumulator = 1调用它。)它等同于以下内容:

function fastExp(base, exponent) {
  var accumulator = 1;
  while(exponent != 0) {
    if(exponent % 2 == 0) {
      base *= base;
      exponent /= 2;
    } else {
      exponent -= 1;
      accumulator *= base;
    }
  }
  return accumulator;
}

所以你可以看到它们是等价的,因此将执行相同数量的操作。

关于c++ - 指数递归与迭代的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8890305/

相关文章:

c++ - 在 Visual Studio 2012 中设置内存断点

java - sun.misc.Perf 文档或替代品

C++ 运行时抢占堆栈溢出

c++ - C++中的哪个塔?

javascript - 如何从 WebAssembly 模块中检测浏览器信息?

.net - 提高 nHibernate 数据访问层的性能

java - 测量 Java 方法重构性能

C#:尽可能高效地将大量文件放入 DVD 的代码

c - Unload() 递归 C Segfault(类似 TRIE 的数据库) CS50 pset5

c++ - std::unordered_map::extract 引用/指针失效