29. Divide Two Integers


思路:這道題讓我們求兩數相除,而且規定我們不能用乘法,除法和取余操作,那么我們還可以用另一神器 位操作Bit Operation,思路是,如果被除數大於或等於除數,則進行如下循環,定義變量t等於除數,定義計數p,當t的兩倍小於等於被除數時,進行如下循環,t擴大一倍,p擴大一倍,然后更新res和m。這道題的OJ給的一些test case非常的討厭,因為輸入的都是int型,比如被除數是-2147483648,在int范圍內,當除數是-1時,結果就超出了int范圍,需要返回INT_MAX,所以對於這種情況我們就在開始用if判定,將其和除數為0的情況放一起判定,返回INT_MAX。然后我們還要根據被除數和除數的正負來確定返回值的正負,這里我們采用長整型long來完成所有的計算,最后返回值乘以符號即可。
用到的知識:左移1位,相當於乘2,右移1位,相當除以2。
第一次提交

int divide(int dividend, int divisor)
{
    int INTMAX = 2147483647;
    int INTMIN = -2147483648;
    if(divisor == 0)
    {
        return INTMAX;
    }
    if(dividend == INTMIN && divisor == -1)
    {
        return INTMAX;
    }
    if(dividend == divisor)
    {
        return 1;
    }
    long long divid = abs((long long)dividend);  //第17行
    long long divis = abs((long long)divisor);
    long res = 0;
    //做符號判斷  //判斷兩個數符號是否相同,可使用按位異或
    int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;  //同號sign=1,異號sign=0
    if((divisor == 1) || (divisor == -1))
    {
        return sign == 1 ? divid : -divid;
    }
    //做除法
    while(divid > divis)
    {
        long long t = divis ,p =1;
        while(divid >= (t << 1))  //左移1位等價於乘2
        {
            t = t << 1;
            p = p << 1;
        }
        res = res + p;
        divid = divid - t;
    }
    return sign == 1 ? res : -res;
}

LeEtcode報錯

Line 17: Char 23: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself (solution.c)

abs的返回值overflow,同時我在本地的編譯器提示我應該使用llabs()函數,abs()函數和llabs()函數的區別如下

int abs( int n );
long labs( long n );
long long llabs( long long n );
__int64 _abs64( __int64 n );

也就是abs()函數的返回值是int類型,當abs()函數的輸入為INT_MIN時,abs()函數將直接返回INT_MIN,這一點在微軟官網上給出了解釋。

我在Qt中做了一個實驗

int main()
{
    printf("%d",abs(INT_MIN));
    return 0;
}

運行結果如下:

第二次提交

int divide(int dividend, int divisor)
{
    int INTMAX = 2147483647;
    int INTMIN = -2147483648;
    if(divisor == 0)
    {
        return INTMAX;
    }
    if(dividend == INTMIN && divisor == -1)
    {
        return INTMAX;
    }
    if(dividend == divisor)
    {
        return 1;
    }
    long long divid = llabs((long long)dividend);
    long long divis = llabs((long long)divisor);
    long res = 0;
    //做符號判斷  //判斷兩個數符號是否相同,可使用按位異或
    int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;  //同號sign=1,異號sign=0
    if((divisor == 1) || (divisor == -1))
    {
        return sign == 1 ? divid : -divid;
    }
    //做除法
    while(divid > divis)
    {
        long long t = divis ,p =1;
        while(divid >= (t << 1))  //左移1位等價於乘2
        {
            t = t << 1;
            p = p << 1;
        }
        res = res + p;
        divid = divid - t;
    }
    return sign == 1 ? res : -res;
}

參考資料:
1 abs,labs,llabs函數的說明 https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/abs-labs-llabs-abs64?view=vs-2017
2 https://www.cnblogs.com/grandyang/p/4431949.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM