Divide Two Integers(两个整数相除)

//参考derrantcm的博客,网址:https://blog.csdn.net/DERRANTCM/article/details/47052683

package algorithm;

/*
 *https://blog.csdn.net/DERRANTCM/article/details/47052683
 * 2个整数相除,不使用除法,乘法,取余 
原题
  Divide two integers without using multiplication, division and mod operator. 
  If it is overflow, return MAX_INT. 

注:multiplication 乘、相乘、增加
division 分开,分割,除法
mod取余
divisor除数


题目大意
  不使用除法,乘法和取余,求两个整数的相除的结果,如果有溢出就返回最大的整数。 

解题思路
  任何一个整数可以表示成以2的幂为底的一组基的线性组合,即num=a_0*2^0+a_1*2^1+a_2*2^2+…+a_n*2^n。基于以上这个公式以及左移一位相当于乘以2,我们先让除数左移直到大于被除数之前得到一个最大的基。然后接下来我们每次尝试减去这个基,如果可以则结果增加加2^k,然后基继续右移迭代,直到基为0为止。因为这个方法的迭代次数是按2的幂知道超过结果,所以时间复杂度为O(log(n))。

具体理解:如 a/b=q     a为被除数,b为除数 ,q为商  
找出n,此时2^n*b<=a<=2^(n+1)*b, 此时商q=0+2^n,
继续a=a-2^n,如果此时 a>2^(n-1)*b,则q=q+2^(n-1),一直到n=0.

例子:100/9=11
a=100,b=9
2^3 *9 <a=100<2^4*9,此时n=3,n最大为3
则商q=0+2^3=8,   100/9=(2^3 *9+28)/9=2^3+28/9=8+28/9
此时a=28 < 2^2*9=36 ,此时n=3-1=2
此时a=28 > 2^1*9=18 ,此时q=8+2^1=10, a=28-18=10
此时a=10 > 2^0*9=9 ,此时n=0 ,q=10+2^0=11 ,a=10-9=1

 * */


public class TwoIntegerDivision {

    //dividend为被除数;divisor为除数;
    public static int getDivision(int dividend,int divisor){
        int min=Integer.MIN_VALUE;//-2147483648 
        int max=Integer.MAX_VALUE; //2147483647
        //System.out.println(min+" "+max);
        if(divisor==0||dividend==min&&divisor==-1){
            return max;
        }
        
        //判断符合  异或(^)
        int sign=((dividend<0)^(divisor<0))?-1:1; //异或  
        
        //被除数,为防止溢出,求绝对值
        long dvd=Math.abs(dividend);
        //除数 求绝对值
        long dvs=Math.abs(divisor);
        
        //遍历被除数>=除数,直到被除数<除数为止
        int result=0;
        while(dvd>=dvs){
        //记录除数
        long tmp=dvs;
        long mul=1; //记录商,即此时的n
        
        while(dvd>=(tmp<<1)){
            tmp=tmp<<1;// 等价于 divisor<<=1;
            mul<<=1; //等价于 result=result<<1
        }
        System.out.println(mul+" "+tmp);//此时为2^n
        
        //除数减去
        dvd=dvd-tmp;
        result=(int) (result+mul);
        }
        
        return result*sign;
        
    }
    
    public static void main(String[] args) {
        //int test=16;
        //System.out.println(test+"左移4位="+(test<<4));
        
        //int test1=1;
        //System.out.println(test1+"左移4位="+(test1<<=4)+"   test1="+test1);
        
        int dvd=100;
        int dvs=9;
        int result=getDivision(dvd,dvs);
        
        System.out.println("算法求解为:"+result+"   直接相除为="+dvd/dvs);
    
        
    }

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值