C++:剑指Offer精讲1.整数除法

题目:001:整数除法


 

1.给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 

注意:

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31−1]。本题中,如果除法结果溢出,则返回 2^31 − 1

 

示例 1:

输入:a = 15, b = 2

输出:7

解释:15/2 = truncate(7.5) = 7

示例 2:

输入:a = 7, b = -3

输出:-2

解释:7/-3 = truncate(-2.33333..) = -2

示例 3:

输入:a = 0, b = 1

输出:0

示例 4:

输入:a = 1, b = 1

输出:1

提示:

-2^31 <= a, b <= 2^31 - 1

b != 0

先展示一下我的代码结果01edf676f3cc46978bd9a3a6093c08f5.jpg

 下面是详细的代码

 

class Solution {
public:
    int divide(int a, int b) {
        if (a == 0 || b == 1) return a;
        if (b == -1 && a == INT_MIN) return INT_MAX;
        int sign = (a > 0 ^ b > 0) ? -1 : 1;
        long la = abs((long)a);
        long lb = abs((long)b);
        long res = 0;
        while (la >= lb) {
            long temp = lb;
            long muti = 1;
            while (la >= temp << 1) {
                temp <<= 1;
                muti <<= 1;
            }
            la -= temp;
            res += muti;
        }
        return sign == 1 ? res : -res;
    };
};

以下是此代码增加注释后的版本:

class Solution {
public:
    // 函数实现除法功能,支持负数
    int divide (int a, int b) {
        // 如果除数是0或者被除数是1,返回被除数
        if (a == 0 || b == 1) return a;
        // 如果除数是-1且被除数是INT_MIN,返回INT_MAX
        if (b == -1 && a == INT_MIN) return INT_MAX;
        // 判断返回值正负号
        int sign = (a > 0 ^ b > 0) ? -1 : 1;
        // 将被除数和除数转为正数
        long la = abs((long)a);
        long lb = abs((long)b);
        // 返回值
        long res = 0;
        // 采用减法的方式实现除法
        while (la >= lb) {
            // 记录除数大小
            long temp = lb;
            // 乘数初始值
            long muti = 1; 
            // 判断被除数是否大于除数*2
            while (la >= temp << 1) {
                // 将除数扩大一倍
                temp <<= 1;
                // 将乘数扩大一倍
                muti <<= 1; 
            }
            // 被除数减去除数*乘数
            la -= temp;
            // 将乘数加入返回值中
            res += muti;       
        }
        // 根据正负号决定返回值
        return sign == 1 ? res : -res;
    }
};

 

程序的步骤如下:

1. 如果除数是0或者被除数是1,返回被除数。
2. 如果除数是-1且被除数是INT_MIN,返回INT_MAX。
3. 判断返回值正负号。
4. 将被除数和除数转为正数。
5. 采用减法来实现除法,即每次将除数乘以一定系数,然后减去该值,直到被除数小于除数为止,每次减去的除数对应的乘数加入返回值中。
6. 根据正负号决定返回值。

 

5.应该是最让人迷糊的,我们来仔细讲解一下5

第5步的目的是模仿除法的运算,减去被除数和乘数的乘积,直到被除数小于除数为止。它首先比较被除数和除数,如果被除数比除数大,就把除数扩大一倍,并把乘数扩大一倍,一直循环,直到被除数小于除数。然后,减去除数和乘数的乘积,并把乘数加入到返回值中,最后根据被除数和除数的正负性来决定返回值的flag。

以被除数为7,除数为3为例来说明减法模拟除法:首先,比较7和3,因为7>3,所以我们将除数变为6,也就是说此时的除数乘以2,乘数也需要乘以2;然后,看被除数和新的除数,发现7<6,所以我们就减去除数乘以乘数,即减去3*2,结果就是7÷3=2。

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lidiyscrp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值