当前位置: 首页 > news >正文

[leetcode.29]两数相除,位运算虽好,不要满眼是她

题目如下

不允许用乘除法,但是我们可以用加减法和位运算。。。不过这里不要用位运算,比如说你要是想用补码交替除法,你根本无法获得移动几位(移动31位?太鬼畜了吧)

所以说单纯的除法部分,我们可以用减法一点一点模拟,暴力不是问题。当然我们也可以使用一种叫做倍速除法的东西,快速计算出整数商 

知识点(1)倍增法:

(这个解释来自leetcode某个题解,实现就是套上两层循环) 

知识点(2)int可能会越界的问题以及处理方式

(1)第一种int可能会越界的情况,加法越界

比如说 2^31-1+2^31-1 > 2^20,这个没啥问题,但是前面太大了,没法计算,会发生越界报错

我们可以转化为a<c-b的形式

不过这个一般要求是同号,为了防止下面的情况我们常用负数,负数容纳量高一点点

(2)正负的最大值不同,如果对负数的最大值取反,结果是2^31,但因为这是补码,正数没法表示那麽大。所以我们遇到可能跃出边界的题,尽量都转化为负数,不会报错的转化方式为

 divisor= divisor>0?-divisor:divisor;

题解如下:

首先先处理唯一的特殊情况,MIN_max/-1,结果会超出界限,这个没法处理,具体题目返回具体的数值吧。

首先先记录符号位

然后把除数和被除数全部转化为负值

(结果也可能是最小值,所以说结果的计算也要是负数,比如Min-max/1的问题)

进行计算

最后按照符号位返回需要的结果

//这题很难用位运算处理。。。因为就算你用了原码交替加减法,还是不知道移动几位
    //只能说位运算是好东西但你不能天天用
    int divide(int dividend, int divisor) {
        if(dividend==-2147483648&&divisor==-1){
            return 2147483647;
        }
        bool sign=(divisor>0&&dividend>0)||(divisor<0&&dividend<0);//记录符号位
        //全部转化为负数,因为计算的时候如果用2的31次方并且转化为正数,就肯定会超出界限
        divisor= divisor>0?-divisor:divisor;
        dividend= dividend>0?-dividend:dividend;
        //下面这个是倍速除法
        int target=dividend;
        int temp;
        int result=0;
        int x=0;
        while(target<=divisor){
            temp=divisor;
            while(temp>=target-temp){//使用这种形式是为了防止越界
                x++;
                temp+=temp;
            }
            target-=temp;
            result-=pow(2,x);
            x=0;
        }
        return sign?-result:result;
    }

 

相关文章:

  • 建设网站需要两种服务支持/安卓优化大师历史版本
  • 重网站建设/成都网站快速优化排名
  • 深圳建设发展集团有限公司/武汉seo网站排名优化公司
  • 做简单网站的步骤/惠州百度关键词优化
  • 那个网站做二手车好/自媒体视频发布平台
  • 关于网站开发的外文书籍/软件外包平台
  • 请问想考软考,零基础的话,哪个证书最好考呢
  • 【手写 Vue2.x 源码】第二十九篇 - diff算法-节点比对
  • java后端-servlet超详细入门
  • mysql性能优化二
  • Python学习中的六个技巧小结
  • ejson4cpp——一个使用极致简单且性能可比rapidjson的C++json解析库
  • 《生命3.0》读后感
  • 笔试强训48天——day29
  • 2023跳槽最新面试题整理——JVM系列
  • 接口超时分析
  • 智慧工地 | 数字孪生楼宇施工管理平台
  • MySQL数据库及数据表相关操作