一.引言

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。返回被除数 dividend 除以除数 divisor 得到的商。整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

Tips:

(1) 结果的符号只需判定除数和被除数是否同符号即可,除法统一转为两正整数相除

(2) 注意数字范围,默认取 int

MAX_INT = int(math.pow(2, 31) - 1)
MIN_INT = int(-math.pow(2, 31))

二.对数偷懒除法

题目要求不能使用乘法,除法和mod,这里可以通过对数减法达到除法的效果:

def logarithmDivide(_dividend, _divisor):st = time.time()if _divisor == 0:return MAX_INTif _dividend == 0:return 0# 判断正负号isPositive = (_dividend < 0) == (_divisor < 0)# 取绝对值m = abs(_dividend)n = abs(_divisor)res = math.log(m) - math.log(n)res = int(math.exp(res))print("对数除法耗时: ", (time.time() - st))if isPositive:return min(res, 2147483647)return max(0 - res, -2147483648)

三.递减法

除法本身其实是减法,可以通过逐级递减获取最终的值:

(1) result = 0

(2) dividend -= divisor; result + 1

(3) 直到 dividend 小于 divisor,退出

def oneByOneDivide(_dividend, _divisor):st = time.time()if _divisor == 0:return MAX_INTif _dividend == 0:return 0# 判断正负号result = 0isPositive = (_dividend < 0) == (_divisor < 0)while _dividend >= _divisor:_dividend -= _divisorresult += 1print("递减除法耗时: ", (time.time() - st))if isPositive:return min(result, 2147483647)return max(0 - result, -2147483648)

四.递减法 Plus

递减法中被除数每次减掉一个除数,当被除数 >> 除数时,程序执行时间很慢,因此可以适当将除数放缩,加快收敛速度:

(1) result = 0,k=1

(2) dividend -= divisor; result + k

(3) divisor *= 2,k *= 2 dividend -= divisor,result += k

(4) divisor 足够大是退出第一个 while,重新从 k=1 开始

(5) dividend 足够小时退出

def multipleDivide(_dividend, _divisor):st = time.time()if _divisor == 0:return MAX_INTif _dividend == 0:return 0# 判断正负号result = 0isPositive = (_dividend < 0) == (_divisor < 0)tmp_dividend = _dividendtmp_divisor = _divisorwhile tmp_dividend >= tmp_divisor:k = 1tmp = tmp_divisorwhile tmp_dividend >= tmp:tmp_dividend -= tmpresult += kk += ktmp += tmpprint("倍数除法耗时: ", (time.time() - st))if isPositive:return min(result, 2147483647)return max(0 - result, -2147483648)

五.递减法 Plussss

上面采用 2 作为递增的倍数,达到了快速收敛的速度,但是当 dividend >> divisor 时,2 指数增长也需要一定步数,此时可以给启动值一个大一点的除数,提高前面的收敛速度,后面被 dividend 和 divisor 差距不大时再退化为 2 指数增长:

def multipleDivideV2(_dividend, _divisor, factor):st = time.time()if _divisor == 0:return MAX_INTif _dividend == 0:return 0# 判断正负号result = 0isPositive = (_dividend < 0) == (_divisor < 0)tmp_dividend = _dividendtmp_divisor = _divisorwhile tmp_dividend >= tmp_divisor:k = 1tmp = tmp_divisor# 加大力度安排while tmp_dividend >= factor * tmp:tmp_dividend -= factor * tmpresult += factor * kk += factor * ktmp += factor * tmp# 退化为2倍数增长收尾while tmp_dividend >= tmp:tmp_dividend -= tmpresult += kk += ktmp += tmpprint("倍数除法耗时: ", (time.time() - st))if isPositive:return min(result, 2147483647)return max(0 - result, -2147483648)

六.总结

给定一个默认除法函数:

def commonDivide(_dividend, _divisor):st = time.time()re = _dividend / _divisorprint("正常除法耗时: ", (time.time() - st))return int(re)

然后比较一个默认除法和上面几种方法的速度差异:

if __name__ == '__main__':dividend = 265783921divisor = 3print(commonDivide(dividend, divisor))print(logarithmDivide(dividend, divisor))print(oneByOneDivide(dividend, divisor))print(multipleDivide(dividend, divisor))print(multipleDivideV2(dividend, divisor, 1000))

速度:common >  logarithm > 加大力度 > 2倍数 >> oneByOne

初始除数给定恰当时,多倍数增长会优于2倍数增长;给的过大或过小时,两者速度相近

正常除法耗时:  1.1920928955078125e-06
88594640
logarithm 对数除法耗时:  3.0994415283203125e-06
88594640
oneByOne 递减除法耗时:  3.9744768142700195
88594640
2倍数增长 倍数除法耗时:  1.7881393432617188e-05
88594640
加大力度安排 倍数除法耗时:  6.9141387939453125e-06
88594640

Python - 两数相除 递进版相关推荐

  1. leetcode第29题python版两数相除

    class Solution:"""29. 两数相除给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.& ...

  2. python 余数_python中两数相除取余数怎么运算

    在Python中取余数可以通过取模运算符%或通过divmod()函数来计算. 1.取模运算符%: 所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b的余数.用数学语言来 ...

  3. Python中获取两数相除的商和余数

    方法一:可以使用//求取两数相除的商.%求取两数相除的余数.[/在Python中获取的是相除的结果,一般为浮点数] 方法二:使用divmod()函数,获取商和余数组成的元祖 实例代码: #!/usr/ ...

  4. Python编程 | 两数相除

    文章目录 两数相除 1,程序简介 示例 1: 示例 2: 提示: 2,程序代码 3,运行结果 两数相除 1,程序简介 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不 ...

  5. (每日一练python)两数相除

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

  6. leetcode —— 29. 两数相除

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数除法的结果 ...

  7. postgre非零相除等于0_LeetCode刷题实战29:两数相除

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  8. LeetCode-中等-29. 两数相除

    LeetCode-中等-29. 两数相除 题目 引用自:LeetCode-中等-29. 两数相除(如有侵权联系删除) 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不 ...

  9. LeetCode 27移除元素28实现strStr()29两数相除

    维护幸苦,如有打卡欢迎关注公众号bigsai回复进群,如有帮助欢迎点赞支持! 移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长 ...

最新文章

  1. 安徽池州贵池中学老师经典语录,我喷了
  2. 腾讯业务监控的修炼之路
  3. Matlab读和写图像需要注意的问题
  4. hibernate 模糊查询及not in子查询
  5. 我们的合作伙伴Datawhale两岁啦!
  6. C语言 数字和字符串的转换 error
  7. linux技巧----查找某个正在执行的脚本
  8. 对象存储,为什么那么火?
  9. 笔记----Linux中pt_regs结构体
  10. java统计计数_java – 使用LongAdder计算统计计数器的最大值?
  11. JavaScript声明全局变量的三种方式
  12. linux centos8安装nginx_如何在 Fedora 30 Server 上安装 LEMP(Linux、Nginx、MariaDB、PHP)| Linux 中国...
  13. STM32中RTC唤醒停止模式
  14. Python数据去重
  15. 数量积与向量积(点积与叉积)
  16. YTU OJ 2476 Problem B C++习题 继承与组合
  17. 挂载NTFS分区导致Docker容器无法启动,Exited (137)错误
  18. leetcode 73 矩阵归零
  19. 西瓜书习题 - 8.集成学习
  20. Liunx userdel删除用户时提示userdel: user *** is currently used by process 12910

热门文章

  1. 这些年,职场上的奇葩领导--华山派
  2. 2023愚人杯-Comedy
  3. php 魔术方法 sleep,PHP 魔术方法: __sleep __wakeup
  4. 鬼谷算题1c语言,《鬼谷学校》谜题小测验,快来看看你能解锁几道题吧!
  5. 一.编写代码完成复制粘贴的功能
  6. [Linux][Colab] Colab连接google云盘 | ssh连接Colab | 防止Colab断连
  7. Cheat engine 下载安装及汉化
  8. 关于Diablo3的历史和现状思考
  9. 汇川中型PLC使用ST语言基础
  10. JAVA第九次作业《第11章-方法的重载-作业-计算工人工资》