【Leetcode】【Divide Two Integers】【两数相除】【C++】

  • 题目:

    给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

    返回被除数 dividend 除以除数 divisor 得到的商。

  • 说明: 
    • 被除数和除数均为 32 位有符号整数。
    • 除数不为 0。
    • 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231,  231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
  • 思路:
    • 本来首先想到的加减计数,例如dividend=15,divisor=3 用15一直减3,看可以减多少次(直到剩余的差小于3),但这样会超时;网上搜索了该题目,阅读了思路和代码好久,才弄懂。现将算法较详细得叙述如下:
      • a) 设divid,divis为dividend,divisor对应的绝对值(溢出情况会另外处理,此处暂不考虑),以divid=73(二进制为:0100 1001),divis=5(二进制为:0101) //注:前面多余的0不再表示; 设一个计数器cnt, 每次cnt求得的结果为(设divis可以左移的最大位数为n,则cnt=2n,换句话说,divis左移log2[cnt]位后,刚好满足divis>divid)
      • b) 初始 divid= 0100 1001  divis=0101  显然,当divis左移4位时,得到 temp=0101 0000,刚好满足temp>divid, 此时cnt=1 0000; 此时temp=(divis*24),由于temp刚好大于divid, 故 divis*23一定小于divid, 即divis*23<divid, 由此可知 divid里面至少有23个divis,故res累加8;
        • 说明:此步骤的关键是求得对应的cnt 用一个while循环即可实现
      • c) 更新 divid=divid-(temp>>1),即 temp=temp- divis*2; 再次循环b)即可 直到divis>divid;
  • 代码:
    class Solution {
    public:
        long long  abs(int n)
        {
            long long n1=n;
            if(n1<0)
                n1=-1*n1;
            return n1;
        }
        int divide(int dividend, int divisor) {
            long long res=0;
    
            int int_min=1<<31;
            int int_max=(int_min>>31) ^ int_min;
    
            long long divid = dividend;
            long long divis = divisor;
    
            bool resNeg = false;
    
            if((divid>0 && divis<0) || (divid<0 && divis>0))
                resNeg = true;
            divid = abs(divid);
            divis = abs(divis);
    
            if(divis==1 && (divid-1)==int_max && !resNeg)
            {
                //cout<<"uicio";
                res=int_max;
                return int_max;
            }
    
            long long cnt=0;
            cout<<divis<<" "<<divid<<endl;
    
            while(divis<=divid)
            {
                cnt=1;
                long long temp=divis;
                while(temp<=divid)
                {
                    temp = temp<<1;
                    cnt = cnt<<1;
                }
                cout<<(cnt>>1)<<endl;
    
                res += (cnt>>1);
                divid -= (temp>>1);
            }
    
            if(resNeg)
                return -1*res;
            return res;
    
        }
    };

    说明:第一个if语句判断商的正负,第二个if语句判断是否溢出;外层while循环累加res,里层while循环求满足条件的cnt和刚好大于divid的temp;

  • 结果: AC
  • 有问题欢迎评论,大家一起交流学习  如有错误,也请不吝赐教;
posted @ 2018-11-11 16:06  dreamer123  阅读(672)  评论(3编辑  收藏  举报