在面试考题里面经常出现处理数值和字符串的函数,这篇文章,我们主要来讲解一个pow、atoi、itoa函数的实现吧~
1、pow函数
1、题目要求
实现函数double Power(double base,int exponent),求base的exponent次方。不得使用库函数,不需要考虑大数问题。
2、题目分析
因为不需要考虑大数问题,首先一拿到这个问题,我们在脑子里面蹦出来的想法就是如下这样实现:
double Power(double base, int exponent)
{
double result = 0;
for (int i = 0; i <= exponent; i++)
{
result *= base;
}
return result;
}
但是这样书写肯定是不对的。这里面存在许多不足
改进一:考虑底数是0且指数是负数的情况
由于有这样一个特殊情况,所以我们要考虑错误处理的方式。
在我们所编写的程序中,通常有三种错误处理的方式,下面展示了他们对应的优缺点
做出的改进代码如下:
bool g_InvalidInput = false;
double Power(double base, int exponent)
{
g_InvalidInput = false;
if (equal(base, 0.0) && exponent < 0)
{
g_InvalidInput = true;
return 0.0;
}
unsigned int absExponent = (unsigned int)(exponent);
if(exponent < 0)
absExponent = (unsigned int)(-exponent);
double result = Powerresult(base, absExponent);
if (exponent < 0)
result = 1.0 / result;
return result;
}
在我们上述的代码中,我们采用全局变量来标识是否出错。如果出错了则返回的值是0。但是具体的为了区分是出错的时候返回的0还是底数为0的时候正常运行返回为0,我们设计了g_InvalidInput全局变量来区分。当出错时,这个变量被设为true,否则为false。
改进二:更加高效的Powerresult方法
如果我们输入的指数exponent为32时,在我们之前的循环里面,我们要做31次循环才可,但是我们仔细想一想似乎还有更简洁的方法。
在这儿我们就要提到在斐波拉契数列中我们提到的一种解法。在求斐波拉契数列里面有一种使用数学公式的方法其时间复杂度是O(logn)其考虑乘方的数学公式如下:
从上面的公式我们可以看出,我们想求改进方法得n次方,就要先得到n/2次方,再把n/2次方的结果平方一下即可。这可以用递归的思路实现。
有了斐波拉契数列的铺垫,我们就更容易思考出该函数的了。因为我们要求的是32次方,由此来计算16次方、8次方、4次方、平方。由此衍生的数学公式如下:
基于上述公式,代码实现如下:
double Powerresult(double base, unsigned int exponent)
{
if (exponent == 0)
return 1;
if (exponent == 1)
return base;
//递归乘法的过程
double result = Powerresult(base, exponent >> 1);
result *