zoukankan      html  css  js  c++  java
  • 重写重要的库函数

    重写幂次函数

    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。

    平方根函数

    在O(logx)的时间复杂度内求解x的平方根,这个题目很容易想到二分查找。但是要注意数据溢出。

    /**
     * @param x: An integer
     * @return: The sqrt of x
     */
    int sqrt(int x) 
    {
    	// write your code here
    	int low = 0;
    	int high = x;
    	while(low <= high)
    	{
    		int mid = low + (high - low) / 2;
    		
    		long long square = (long long)mid * (long long)mid;//这里一定要先做类型的转换,不然还是会数据溢出的
    		if(square == x)
    		{
    			return mid;
    		}
    		else if(square > x)
    		{
    			high = mid - 1;
    		}
    		else
    		{
    			long tmp = (long long)(mid + 1) * (long long)(mid + 1);
    			if(tmp > x)
    				return mid;
    			else
    				low = mid + 1;
    		}
    	}//while
    }
    

      

  • 相关阅读:
    NET中的类型和装箱/拆箱原理
    转 C# 装箱和拆箱[整理]
    理解线程同步
    IsBackground的理解
    赛马会面试题
    FTP上传类
    FTPS加密上传
    转载WPF SDK研究 之 AppModel
    SQL Server查看错误日志存档编号及其详情
    Hive基础编程入门(一)
  • 原文地址:https://www.cnblogs.com/stemon/p/4665430.html
Copyright © 2011-2022 走看看