题29、两数相除

一、题目1

在这里插入图片描述

二、思路

思路一:

暴力循环,判断当前剩余的部分能不能进行减一操作(假定是两个正数相除),能就继续,不能就结束并返回结果。

难点在于对什么时候停止循环进行判断,因为有符号不同这种情况。
最后我的解决办法就是依旧判断是否的大于(假定正数除以负数),这样就多循环了两次,最后在结果中减去就ok了,然后最后提交超时,据我判断是倒在了-231这个边界值上面了,可以输出结果,但是,超时。

思路二:

这个思路主要的依据就是对任何一个整数n有:n=2n×a+2n-1×a+……+21×a+20×a

然后就通过移位运算,最后得到结果。

补充:

对于符号的解决方法:我下面的代码中思路一是根据不同的符号进行判断,然后进行相应的方法。
思路二的办法是将其均转化为正数进行计算。

然后提交看了大佬的代码之后发现,转化为负数计算更加的方便,因为正数转负数不会越界,负数转正数存在越界的情况。

三、代码

public class T0029 {

    public T0029() {

        System.out.println( divide( -2147483647, 2 ) +" \t" + (-2147483647/2));
        System.out.println( divide( -2147483647, -2 ) +" \t" + (-2147483647/-2));
        System.out.println( divide( 2147483647, 2 ) +" \t" + (2147483647/2));


        System.out.println( divide( 2147483647, 1 ) +" \t" + (2147483647/1));
        System.out.println( divide( -2147483648, 1 ) +" \t" + (-2147483648/1));
        System.out.println( divide( 2147483647, -1 ) +" \t" + (2147483647/-1));
        System.out.println( divide( -2147483648, -1 ) +" \t" + (-2147483648/-1));


        for ( int i = 0; i < 10; i++ ){
            int a = (int)(Math.random()*1000);
            int b = (int)(Math.random()*100);
            System.out.println( divide( a, b ) == (a/b) );
        }

        for ( int i = 0; i < 10; i++ ){
            int a = (int)(Math.random()*1000);
            int b = (int)(Math.random()*100);
            System.out.println( divide( -a, b ) == (-a/b) );
        }

        for ( int i = 0; i < 10; i++ ){
            int a = (int)(Math.random()*1000);
            int b = (int)(Math.random()*100);
            System.out.println( divide( a, -b ) == (a/-b) );
        }

        for ( int i = 0; i < 10; i++ ){
            int a = (int)(Math.random()*1000);
            int b = (int)(Math.random()*100);
            System.out.println( divide( -a, -b ) == (-a/-b) );
        }

    }

    public int divide(int dividend, int divisor) {

        //判断是否是被除数为0,被除数除数均为最小值,除数为最小值
        //并对相应的情况进行处理
        if ( dividend == 0 || divisor==Integer.MIN_VALUE){
            return dividend==Integer.MIN_VALUE?1:0;
        }

        int a = 0;                      //被除数的绝对值
        int b = Math.abs(divisor);      //除数的绝对值
        boolean special = false;        //被除数是否是最小值

        int result = 0;                 //商
        int tmp = b;                    //暂时存储移位的结果
        int stape = 1;                  //暂时存储当前移位的值

        //判断被除数是否是最小值,并取其绝对值
        if ( dividend != Integer.MIN_VALUE ){
            a = Math.abs(dividend);
        }else {
            a = Math.abs(dividend+1);
            special = true;
        }

        //当被除数小于除数时循环结束
        while ( a >= b ){

            //判断此次位移结果是否会越界
            //不越界就进行位移,可能会越界就进行加减和初始化操作
            if ( tmp < Integer.MAX_VALUE >> 2 ){

                //当位移结果小于被除数时,继续进行位移操作
                //当大于时,就用被除数减去位移结果,并将stape的值加在result上
                //同时将结果tmp、stape再次初始化
                if ( tmp<<2 < a ){
                    tmp = tmp<<2;
                    stape = stape<<2;
                }else {
                    a = a - tmp;
                    tmp = b;
                    result +=stape;
                    stape = 1;
                }
            }else{
                a = a - tmp;
                tmp = b;
                result +=stape;
                stape = 1;
            }
        }

        //将result的符号修正
        if ( (dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0))
            result = -result;

        //若被除数是最小值,将上面减去的1重新加回来,并进行计算
        if ( special && a+1==b ){

            //判断计算结果是否会越界
            if (result== Integer.MAX_VALUE)
                return Integer.MAX_VALUE;
            else
                result = result-1;
        }

        return result;
    }


    public int divide1(int dividend, int divisor) {

        if ( dividend == 0 ){
            return 0;
        }
        int result = 0;
        int tmp = divisor;
        int stape = 1;

        if ( dividend>0&&divisor>0 ){
            while ( dividend >= divisor ){

                if ( tmp < Integer.MAX_VALUE >> 2 ){
                    if ( tmp<<2 < dividend ){
                        tmp = tmp<<2;
                        stape = stape<<2;
                    }else {
                        dividend = dividend - tmp;
                        tmp = divisor;
                        result +=stape;
                        stape = 1;
                    }
                }else{
                    dividend = dividend - tmp;
                    tmp = divisor;
                    result +=stape;
                    stape = 1;
                }

            }
        }else if ( dividend>0&&divisor<0 ){
            while ( dividend >= divisor ){

                if ( tmp < Integer.MIN_VALUE >> 2 ){
                    if ( tmp<<2 < dividend ){
                        tmp = tmp<<2;
                        stape = stape<<2;
                    }else {
                        dividend = dividend + tmp;
                        tmp = divisor;
                        result -=stape;
                        stape = 1;
                    }
                }else{
                    dividend = dividend + tmp;
                    tmp = divisor;
                    result -=stape;
                    stape = 1;
                }

            }

            result += 2;

        }else if ( dividend<0&&divisor>0 ){
            while ( dividend <= divisor ){

                if ( tmp < Integer.MIN_VALUE >> 2 ){
                    if ( tmp<<2 < dividend ){
                        tmp = tmp<<2;
                        stape = stape<<2;
                    }else {
                        dividend = dividend + tmp;
                        tmp = divisor;
                        result -=stape;
                        stape = 1;
                    }
                }else{
                    dividend = dividend + tmp;
                    tmp = divisor;
                    result -=stape;
                    stape = 1;
                }

            }

            result += 2;

        }else {
            while ( dividend <= divisor ){

                if ( result == Integer.MAX_VALUE )
                    return Integer.MAX_VALUE;

                if ( tmp < Integer.MIN_VALUE >> 2 ){
                    if ( tmp<<2 < dividend ){
                        tmp = tmp<<2;
                        stape = stape<<2;
                    }else {
                        dividend = dividend - tmp;
                        tmp = divisor;
                        result +=stape;
                        stape = 1;
                    }
                }else{
                    dividend = dividend - tmp;
                    tmp = divisor;
                    result +=stape;
                    stape = 1;
                }

            }
        }

        return result;
    }

    public static void main(String[] args) {

        T0029 t0029 = new T0029();
    }
}

  1. 来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/divide-two-integers
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 ↩︎

发布了48 篇原创文章 · 获赞 1 · 访问量 838

猜你喜欢

转载自blog.csdn.net/weixin_45980031/article/details/104380924