leetcode 29. Divide Two Integers

0 题目

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

意思是不适用除法,乘法,取模,计算两个数相除。

另外,如果越界,返回MAX_INT

1 分析

难点有两个:

  1. 越界检查
  2. 只能用加减和位运算

1.1 什么时候会越界

两个有符号数相除

  1. 当除数是0的时候,越界
  2. 当被除数是MIN_INT,除数是-1的时候,结果应该是INT_MAX+1.越界 (INT_MAX = -INT_MAX-1),最大值和最小值在绝对值上,最小值是要大1的。

1.2 使用加减计算除法

首相想到的是挨个相减,减一次,结果+1,但是,太慢。

因此需要成倍的减。

 1.3 符号的判断

  1. 点号、e只能出现一次
  2. -+在开头或是e后第一个字符是可以的
  3. 最后一位不能是+ - ,e
  4. 单独一个.是错误的
  5. 开头是e是错误的
int divide(int a, int b)
{
    if (b == 0) //判断除数为0,
    {
        return INT_MAX;
    }

    if (a == INT_MIN && b == -1) // 因为 INT_MIN 数值上比 INT_MAX 大 1 ,因此 INT_MIN/-1 会越界
    {
        return INT_MAX;
    }

    int tmp_ret = 0;

    // 这一步判断需要在前面,因为(INT_MIN,INT_MIN)的情况。
    if (a == 0)
    {
        return 0;
    }

    // 后面需要将 a,b 取绝对值运算,因此不能存在 a== INT_MIN
    // b 可以为 INT_MIN ,因为 abs 后 b 仍然等于 INT_MIN,这里没看懂!!!
    if (a == INT_MIN)
    {
        if (b < 0)
        {
            a -= b;
            ++tmp_ret;
        }
        else
        {
            a += b;
            --tmp_ret;
        }
    }

    bool sign = (a < 0 && b < 0) || (a > 0 && b > 0) ? true : false;

    a = abs(a);
    b = abs(b);

    int ret = 0;

    int tmp_b = b;

    while (a - tmp_b >= 0)
    {
        int ret_tmp = 1;
        while (a - tmp_b > tmp_b)
        {
            tmp_b += tmp_b;//每次递增
            ret_tmp += ret_tmp;
        }
        a -= tmp_b;
        ret += ret_tmp;
        tmp_b = b;
    }

    return sign ? ret + tmp_ret : -ret + tmp_ret;
}

  

有些步骤是根据调试出来的结果。因此有种投机取巧的感觉。

原文地址:https://www.cnblogs.com/perfy576/p/8552436.html