首页 > 图灵资讯 > 技术篇>正文
java 两总数相除取整 java两个整数相除
2023-05-17 11:35:49
算法问题:整数除法详解(Java方向)
- 1.力扣题目
- 2.结果代码分析
- 3.完整的结果代码
- 4.代码来源和教学来源
- 5.博主 边学习边记录算法。
1.给定两个整数 a 和 b ,求他们除法的商人 a/b? 2.要求:不得使用 乘号 '*'、除号 '/' 、求余 '%' 。
2.结果代码分析
if (a == Integer.MIN_VALUE && b == -1) { return Integer.MAX_VALUE; }
1.首先判断参数的边界值。若被除数a是整形手术的最小值,且除数b为-1,则正常操作的结果为被除数a本身。 实际情况:结果是整形手术的最大值,因此需要排除这种情况。遇到情况,直接返回结果即可。 (1)Integer.MIN_VALUE相关: 1.在JDK中,整形手术的类型是有范围的, 2.Integer最大值.MAX_VALUE,即2147483647。 3.Integer最小值.MIN_VALUE,即-2147483648。 4.整形最大值加1,即2147483648。结果是-2147483648,即Integer.MIN_VALUE。 5.对Integer.MIN_VALUE取反或取绝对值,其结果为-2147483648,即Integer.MIN_VALUE。(因为取反后整形达到超出范围,成为最小值) (2)&&相关: 1.&&运算符是 短路与 运算。 2.如果&&左边的表达值是 false,右侧的表达式会直接短路,不会操作。
int sign = (a > 0) ^ (b > 0) ? -1 : 1;
2.其次,正负判断被除数a和除数b。如果除数a和除数b大于0,则返回-1;若一方为负,则返回1。 实际情况:记录a和b是否大于0后,作用于最终结果的符号判断。 (1)^(根据位异或)相关: 1.运算符是 按位异或 运算。 2.任何相同的二进制位进行^操作,结果为0;任何不同的二进制位 ^ 结果为1。 (2)(条件表达式)表达式1:表达式2 相关: 1.首先判断条件表达值,如果是true,则计算结果为表达式1;若为false,运算结果为表达式2。
a = Math.abs(a); b = Math.abs(b);
3.然后,对于被除数a、除数b 都取绝对值。 (1)Math.abs() 相关:获得其绝对值。如果参数等于 Integer.MIN_VALUE 值(即可表示的最小负值) int 值),结果与该值相同且为负。
int res = 0;
4.然后,初始化结果res。
for (int i = 31; i >= 0; i--) {
if ((a >>> i) - b >= 0) {
a -= (b << i) ;
if (res > Integer.MAX_VALUE - (1 << i)) {
return Integer.MIN_VALUE;
}
res += (1 << i);
}
}
5.然后在for循环中编写逻辑,i从31开始递减,循环。(每次尝试从最大位数开始) 1)如果 被除数a右移i后,与除数b相减大于0,继续判断。 2)重要逻辑:除法和乘法不能使用后,减法减去除数b可以用来判断商家。 为了提高代码效率,使用位运算符减去被除数a 除数b2的i次幂 使用减法判断商。 3)代码优化:res += (1 << i); 这里控制 res 大于等于 INT_MAX PS:无符号右移为将军 Int最小值 看成 2147483648,不用担心越界。以(a >>> i) - b >= 0格式,可以防止:除数b是最小值,导致永远是true的情况。 (1)>>>相关:无符号右移在表达式中执行。
return sign == 1 ? res : -res;
6.最后,由于乘号不能使用,乘号被三目运算符取代
3.完整的结果代码
// 时间复杂:O(1) public int pide(int a, int b) { if (a == Integer.MIN_VALUE && b == -1) return Integer.MAX_VALUE; int sign = (a > 0) ^ (b > 0) ? -1 : 1; a = Math.abs(a); b = Math.abs(b); int res = 0; for (int i = 31; i >= 0; i--) { // 首先,如果右移,不管怎样,都不会越界 // 其次,无符号右移的目的是:将 -2147483648 看成 2147483648 // 注意,这里不能是 (a >>> i) >= b 而应该是 (a >>> i) - b >= 0 // 这也是为了避免 b = -2147483648,如果 b = -2147483648 // 那么 (a >>> i) >= b 永远为 true,但是 (a >>> i) - b >= 0 为 false if ((a >>> i) - b >= 0) { // a >= (b << i) a -= (b << i); // 代码优化:此处控制 res 大于等于 INT_MAX if (res > Integer.MAX_VALUE - (1 << i)) { return Integer.MIN_VALUE; } res += (1 << i); } } // bug 修理:由于乘号不能使用,因此,乘号被三目运算符号取代 return sign == 1 ? res : -res; }
4.博主 边学习边记录算法。
欢迎大家评论指导。第一次写博客有很多错误,希望对一小部分人有所帮助。祝大家早日推开算法成神之路。