使用递归将基数提高到其指数-C++
Using Recursion to raise a base to its exponent - C++
我只想写一些代码,利用函数的递归来提高基数。我知道递归不是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"的答案!有人能帮我吗?
int raisingTo(int base, unsigned int exponent)
{
if (exponent == 0)
return 1;
else
return base * raisingTo(base, exponent - 1);
}
你有3个主要问题:
- 你不必使用pow函数
- 要比较数字,您应该使用
==
,因为=
是一个赋值,而不是比较 - 您忽略了如果指数等于0,则应返回1
要使其成为一个实际的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·be-1,即
- b18。现在18可以被2整除,所以我们对be/2求平方,这就是
- b9。其中9可被3整除,因此我们对be/3进行立方运算,即
- b3。其中3可被3整除,因此我们对be/3进行立方运算,即
- b1,即b
这只是1+1+2+2=6次乘法,是循环方法所需数量的1/3!但是,请注意,这并不一定意味着代码执行得更快,因为检查因素也需要一些时间。特别是,unsigned
s上的%3
可能并不比int
s上的乘法快,所以对于NumT==int
来说,它一点也不聪明。但对于更昂贵的浮点类型complex
来说,是聪明的,更不用说乘法可能非常昂贵的线性代数矩阵类型了。
您的问题在于
if (exponent > 0)
return 1;
else if (exponent = 0)
首先,您反转了条件(如果指数等于零,它应该返回),其次,您正在赋值,而不是与第二个if
进行比较。
这里有一个更复杂的版本(O(lg exponent)
,而不是O(exponent)
),它在概念上类似于leftround的版本。
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);
}
它还使用尾部递归,这通常会导致更好地优化机器代码。
这里有一个关于O(logn)复杂性的更清晰的解释
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
级
信息源
- 使用简单类型列表实现的指数编译时间.为什么
- 如何从组合指数中找到仓位
- 正在读取 obj 文件!(指数)
- C++:快速模块化指数
- 在C++不使用 POW 的情况下处理负指数
- 比较向量中的元素时所花费的时间呈指数级增长
- 如何将包含指数的 QString 转换为C++中的双倍?
- 将数字提高到一个巨大的指数
- 负指数是否必然意味着未定义的行为
- 整数的指数速记
- 在矩阵逆变器上工作,由于某种原因,我的指数循环不起作用
- 自定义提升多精度指数中的位数
- 如何计算复矩阵的指数
- 用C++打印指数形式的素数分解
- 为什么Regex(c++)需要指数时间
- 指数近似不适合小输入或大输入
- 如果 std::numeric_limits<float>::is_iec559 为真,这是否意味着我可以以明确定义的方式提取指数和尾数?
- 在 c++ 中创建具有指数分布的随机数(可视化标准)
- 使用双精度运算的快速 SSE 低精度指数
- C ++指数计算器错误