热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Leetcode】【DivideTwoIntegers】【两数相除】【C++】

题目:给定两个整数,被除数dividend和除数divisor。将两数相除,要求不使用乘法、除法和mod运算符。返回被除数dividend除以除数divisor得到的商。
  • 题目:

    给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

    返回被除数 dividend 除以除数 divisor 得到的商。

  • 说明: 
    • 被除数和除数均为 32 位有符号整数。
    • 除数不为 0。
    • 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231,  231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
  • 思路:
    • 本来首先想到的加减计数,例如dividend=15,divisor=3 用15一直减3,看可以减多少次(直到剩余的差小于3),但这样会超时;网上搜索了该题目,阅读了思路和代码好久,才弄懂。现将算法较详细得叙述如下:
      • a) 设divid,divis为dividend,divisor对应的绝对值(溢出情况会另外处理,此处暂不考虑),以divid=73(二进制为:0100 1001),divis=5(二进制为:0101) //注:前面多余的0不再表示; 设一个计数器cnt, 每次cnt求得的结果为(设divis可以左移的最大位数为n,则cnt=2n,换句话说,divis左移log2[cnt]位后,刚好满足divis>divid)
      • b) 初始 divid= 0100 1001  divis=0101  显然,当divis左移4位时,得到 temp=0101 0000,刚好满足temp>divid, 此时cnt=1 0000; 此时temp=(divis*24),由于temp刚好大于divid, 故 divis*23一定小于divid, 即divis*233个divis,故res累加8;
        • 说明:此步骤的关键是求得对应的cnt 用一个while循环即可实现
      • c) 更新 divid=divid-(temp>>1),即 temp=temp- divis*2; 再次循环b)即可 直到divis>divid;
  • 代码:
    class Solution {
    public:
        long long  abs(int n)
        {
            long long n1=n;
            if(n1<0)
                n1=-1*n1;
            return n1;
        }
        int divide(int dividend, int divisor) {
            int res=0;
    
            int int_min=1<<31;
            int int_max=(int_min>>31) ^ int_min;
    
            long long divid = dividend;
            long long divis = divisor;
    
            bool resNeg = false;
    
            if((divid>0 && divis<0) || (divid<0 && divis>0))
                resNeg = true;
            divid = abs(divid);
            divis = abs(divis);
    
            if(divis==1 && (divid-1)==int_max && !resNeg)
            {
                //cout<<"uicio";
                res=int_max;
                return int_max;
            }
    
            long long cnt=0;
            cout<" "<endl;
    
            while(divis<=divid)
            {
                cnt=1;
                long long temp=divis;
                while(temp<=divid)
                {
                    temp = temp<<1;
                    cnt = cnt<<1;
                }
                cout<<(cnt>>1)<<endl;
    
                res += (cnt>>1);
                divid -= (temp>>1);
            }
    
            if(resNeg)
                return -1*res;
            return res;
    
        }
    };

    说明:第一个if语句判断商的正负,第二个if语句判断是否溢出;外层while循环累加res,里层while循环求满足条件的cnt和刚好大于divid的temp;

  • 结果: AC
  • 有问题欢迎评论,大家一起交流学习  如有错误,也请不吝赐教;

推荐阅读
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • SCJP认证全称为SUN认证Java程序员,是Java认证系列中最基础的一门认证。要通过Java的其他认证,必须先通过SCJP认证(SCEA认证除外)。即使SUN被Oracle收购 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [线段树|平衡树|树状数组]LightOJ - 1087 - Diablo
    1087-DiabloPDF(English)StatisticsForum ... [详细]
  • ProblemDescriptionXiaoAlivesinavillage.Lastyearfloodrainedthevillage ... [详细]
  • 自动调整列的宽度functionDBGridRecordSize(mColumn:TColumnEh):Boolean;{返回记录数据网格列显示最大宽度是否成功}beginResu ... [详细]
author-avatar
济河南岸_797
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有