首页 > 图灵资讯 > 技术篇>正文

java 两总数相除取整 java两个整数相除

2023-05-17 11:35:49

算法问题:整数除法详解(Java方向)

  • 1.力扣题目
  • 2.结果代码分析
  • 3.完整的结果代码
  • 4.代码来源和教学来源
  • 5.博主 边学习边记录算法。
1.力扣题目
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.博主 边学习边记录算法。
欢迎大家评论指导。第一次写博客有很多错误,希望对一小部分人有所帮助。祝大家早日推开算法成神之路。

上一篇 检查Java的所有端口 检查java环境是否配置成功
下一篇 如何在 Java 8 中使用 Streams

文章素材均来源于网络,如有侵权,请联系管理员删除。