使用Recursion将基数提升到其指数 - C ++

时间:2012-02-19 11:59:28

标签: c++ recursion pow

我只是想编写一些代码,这些代码利用函数的递归来提高函数的基础。我知道递归不是用C ++做事的最正确方法,但我只是想稍微探讨一下这个概念。该程序要求用户提供基数和指数,然后控制台输出答案。这是我写的程序:

#include <iostream>
#include <math.h>
using namespace std;

int raisingTo(int, int);
int main()
{
    int base, exponent;
    cout << "Enter base value: ";
    cin >> base;
    cout << "Enter exponent value: ";
    cin >> exponent;
    int answer = raisingTo(base, exponent);
    cout << "The answer is: " << answer << endl;
    char response;
    cin >> response;
    return 0;
}

int raisingTo(int base, int exponent)
{
    if (exponent > 0)
        return 1;
    else if (exponent = 0)
    {
        int answer = (int) pow((double)base, raisingTo(base, (exponent - 1)));
        return answer;
    }
}

有趣的是,当我运行这个程序时,它会一直将答案返回为“1”!有人可以帮我这个吗?

5 个答案:

答案 0 :(得分:8)

int raisingTo(int base, unsigned int exponent)
{
    if (exponent == 0)
        return 1;
    else
        return base * raisingTo(base, exponent - 1);
}

您有3个主要问题:

  • 您不必使用pow功能
  • 要比较数字,您应使用==,因为=是一项不比较的作业。
  • 你错过了如果指数等于0,你应该返回1.

答案 1 :(得分:2)

要使这成为一个真正的C ++答案 - 这是一种你可以考虑将其作为模板函数的任务,因为这应该适用于任何类型的数字类型。

递归 实际上是一个好主意,但只有当你利用它可以提供的好处时:它可以通过从指数中分解出低数来避免一些乘法。

template <typename NumT>
NumT raiseTo(NumT base, unsigned exponent) {
  if (exponent == 1) return base;
  if (exponent == 0) return 1;
  if (exponent%2 == 0) { NumT ressqrt = raiseTo(base,exponent/2)
                       ; return ressqrt*ressqrt;                  }
  if (exponent%3 == 0) { NumT rescubrt = raiseTo(base,exponent/3)
                       ; return rescubrt*rescubrt*rescubrt;       }
  else return base * raiseTo(base, --exponent);
}

这可以节省多少计算的示例:假设您想要将数字提高到19.如果您使用天真的循环方法,那么这是18次乘法。有了这个解决方案,会发生什么

  • 19不能被2或3整除,因此计算 b b e -1 ,这是
  • B'/ EM> 18 。现在18可以被2整除,所以我们将 b e / 2
  • B'/ EM> 9 。其中9可以被3整除,所以我们立方体 b e / 3 ,这是
  • B'/ EM> 3 。其中3可以被3整除,所以我们立方体 b e / 3 ,这是
  • b 1 ,即b。

这只是1 + 1 + 2 + 2 = 6次乘法,是循环方法所需数量的1/3!但请注意,这并不一定意味着代码执行速度会更快,因为检查因素也需要一些时间。特别是,%3上的unsigned可能不会比int上的乘法更快,因此对于NumT==int来说,它根本不是很聪明。但对于更昂贵的浮点类型complex,它 更聪明,更不用说线性代数矩阵类型,其乘法可能非常昂贵。

答案 2 :(得分:1)

你的问题就在这里

if (exponent > 0)
    return 1;
else if (exponent = 0)

首先,你已经颠倒了条件(如果指数等于零,它应该返回),其次,你正在分配而不是与第二个if进行比较。

答案 3 :(得分:1)

这是一个复杂性更高的版本(O(lg exponent),而不是O(exponent)),这在概念上类似于leftroundabout的版本。

int raisingTo(int base const, unsigned int const exponent, int scalar = 1)
{
    if (exponent == 0)
        return scalar;

    if (exponent & 1) scalar *= base;
    return raisingTo(base * base, exponent >> 1, scalar);
}

它还使用尾递归,这通常会导致更好的机器代码。

答案 4 :(得分:0)

以下是O(log n)复杂度的清晰解释

public int fastPower(int base , int power){

if ( power==0 )
  return 1 
else if(power %2 == 0 )
  return fastPower(base*base,power/2)
else
 return base * fastPower(base,power-1)
}

这个算法遵循以下简单的指数规则

base^0 = 1
base^power = base*base^(power-1)
base^(2*power) = (base^2)^power

因此,在每个级别,n的值都是它的一半或者它小于n。因此,递归将会变为1+log n级别

信息source