题目: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
先展示一下我的代码结果
下面是详细的代码
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。