每日一题「整数除法」

举报
陈皮的JavaLib 发表于 2022/04/05 11:59:38 2022/04/05
【摘要】 输入2个 int 型整数,将它们进行除法计算并返回商,要求不得使用乘号、除号及求余符号。当发生溢出时,返回最大的整数值。假设除数不为0。例如,输入15和2,输出15/2的结果,即7。

我是陈皮,一个在互联网 Coding 的 ITer,个人微信公众号「陈皮的JavaLib」关注第一时间阅读最新技术文章。

题目

输入2个 int 型整数,将它们进行除法计算并返回商,要求不得使用乘号、除号及求余符号。当发生溢出时,返回最大的整数值。假设除数不为0。例如,输入15和2,输出15/2的结果,即7。

分析

限制了不可以使用除法,乘法,和求余运算,那么可以使用减法来实现除法。

例如15/2,不断地从15里减去2,当减去7个2之后余数是1,余数不能再减去2,所以15/2的商是7。使用一个循环即可实现这个过程。

不过,但当被除数很大但除数很小时,减法操作执行的次数会很多。例如,当被除数为 int 类型的最大值 2^31 - 1,除数为1时,减1操作次数为 2^31 - 1 次。当除数为2时,减2操作次数也要 2^30 次左右。这样会导致算法速度很慢。

所以我们需要优化,如果被除数大于除数时,判断被除数是否大于除数的2倍,如果是,再判断是否4倍,8倍…,直到最多2n倍。然后将被除数减去2n个除数,2n的值累加到总的减次数中,将剩余的被除数继续重复以上操作,直到剩余的被除数小于除数。因为每次将除数翻倍,所以时间复杂度是O(logn)。

因为被除数和除数都有可能是负数,为方便计算,需要先将它们都转为同符号的整数,计算出结果后,再进行对商调整符号。如果将负数都调整为正数,有可能会发生溢出,例如负数-2^31,但是正数最大值是2^31-1。所以我们选择将正数转为负数,对两个负数进行除法求商,最后再对商的符号进行调整。

实现

package com.chenpi;

/**
 * @author 陈皮
 * @version 1.0
 * @description
 * @date 2022/3/17
 */
public class ChenPi {

  public static void main(String[] args) {
    ChenPi inst = new ChenPi();
    int dividend = -18;
    int divisor = 3;
    System.out.println(inst.divide(dividend, divisor));
  }

  public int divide(int dividend, int divisor) {

    // 这种情况会发生溢出
    if (dividend == Integer.MIN_VALUE && divisor == -1) {
      return Integer.MAX_VALUE;
    }

    // 记录负号的个数
    int negativeCount = 2;

    // 被除数如果为正数转为负数
    if (dividend > 0) {
      dividend = -dividend;
      negativeCount--;
    }

    // 除数如果为正数转为负数
    if (divisor > 0) {
      divisor = -divisor;
      negativeCount--;
    }

    // 商
    int result = 0;

    // 被除数小于除数时(因为它们都是负数),重复
    while (dividend <= divisor) {
      // 记录最大的|除数*2n|绝对值
      int timesValue = divisor;
      // 减去除数的次数
      int times = 1;
      // 最小值是-2^31,0xc0000000是-2^30,避免timesValue是-2^31时,timesValue + timesValue发生溢出
      while (timesValue >= 0xc0000000 && dividend <= timesValue + timesValue) {
        times += times;
        timesValue += timesValue;
      }
      result += times;
      dividend -= timesValue;
    }

    // 商符号调整
    return negativeCount == 1 ? -result : result;
  }

}

输出结果

-6

本次分享到此结束啦~~

如果觉得文章对你有帮助,点赞、收藏、关注、评论,您的支持就是我创作最大的动力!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。