码迷,mamicode.com
首页 > 其他好文 > 详细

重写重要的库函数

时间:2015-08-31 06:26:27      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

重写幂次函数

pow(double base, int exp);

首先要写一些测试用例:

1.base=0时,exp<=0是不合法的输入。
2.base不等于0,exp<0时,要计算的值是base的|exp|次幂,然后取倒数。
3.base不等于0,exp>0时,直接计算base的|exp|次幂。

代码实现:

double myPow(double x, int n) 
{
	if(equalZero(x, 0.0) && n <= 0)
	{
		return 0.0;
	}
	
	int absExp = n;
	if(n < 0)
	{
		absExp = -n;
	}
	
	double res = getPowWithAbsExp(x, absExp);
	
	if(n < 0)
		res = 1.0 / res;
		
	return res;
}

double getPowWithAbsExp(double base, int absExp)
{
	double result = 1.0;
	for(int i = 0; i < absExp; ++i)
	{
		result *= base;
	}
	
	return result;
}

bool equalZero(double num1, double num2)
{
	double delt = 0.0001;
	if((num1 - num2 < delt) && (num1 - num2 > -delt))
	{
		return true;
	}
	else 
	{
		return false;
	}
}//equalZero()

  但是这时新的问题来了,如果exp很大,那么这个样子的连乘,肯定需要很大的时间复杂度。这里利用到了归并排序的思想,把相同的小的子问题,配对计算,得出中等的问题,然后再把中等的问题配对计算,最后得到大的问题的解。这一点很像合并K个有序的链表中用到的方法。

所以新的getPowWithAbsExp函数可以这样写:

double getPowWithAbsExp(double base, int absExp)
{
	double result = 0.0;
	if(absExp == 0)
		return 1.0;
	if(absExp == 1)
		return base;
		
	result = getPowWithAbsExp(base, absExp / 2);
	result *= result;
	
	if(absExp % 2 != 0)
		result *= base;
	
	return result;
}

  这样就通过归并的方法,大大的减少了计算乘法的次数

重写memmove函数

在内存复制的时候,如果两段内存有重叠,那么就很容易产生覆盖。所以重写这个函数,对有重叠的内存的拷贝进行处理。

void* memmove(void* str1,const void* str2,int n)
{
    char* pStr1 = (char*) str1;
    const char* pStr2 = (const char*)str2;

    if(pStr1 < pStr2)	//从前面开始copy
	{
        for(int i=0; i!=n; ++i)
		{
            *(pStr1++) = *(pStr2++);
        }
    }
    else	//从后面开始copy
	{
        pStr1 += n-1;
        pStr2 += n-1;
        for(int i=0; i!=n; ++i)
		{
            *(pStr1--) = *(pStr2--);
        }
    }

    return pStr1;
}

  为了避免把还未copy的内存区域覆盖掉,这里用到的解决办法就是根据两块内存的位置,从前面或者后面进行内存copy。

技术分享

重写重要的库函数

标签:

原文地址:http://www.cnblogs.com/stemon/p/4665430.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!