Python - 两数相除 递进版
一.引言
给定两个整数,被除数 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 - 两数相除 递进版相关推荐
- leetcode第29题python版两数相除
class Solution:"""29. 两数相除给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符.& ...
- python 余数_python中两数相除取余数怎么运算
在Python中取余数可以通过取模运算符%或通过divmod()函数来计算. 1.取模运算符%: 所谓取模运算,就是计算两个数相除之后的余数,符号是%.如a % b就是计算a除以b的余数.用数学语言来 ...
- Python中获取两数相除的商和余数
方法一:可以使用//求取两数相除的商.%求取两数相除的余数.[/在Python中获取的是相除的结果,一般为浮点数] 方法二:使用divmod()函数,获取商和余数组成的元祖 实例代码: #!/usr/ ...
- Python编程 | 两数相除
文章目录 两数相除 1,程序简介 示例 1: 示例 2: 提示: 2,程序代码 3,运行结果 两数相除 1,程序简介 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不 ...
- (每日一练python)两数相除
两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数 ...
- leetcode —— 29. 两数相除
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数除法的结果 ...
- postgre非零相除等于0_LeetCode刷题实战29:两数相除
算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...
- LeetCode-中等-29. 两数相除
LeetCode-中等-29. 两数相除 题目 引用自:LeetCode-中等-29. 两数相除(如有侵权联系删除) 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不 ...
- LeetCode 27移除元素28实现strStr()29两数相除
维护幸苦,如有打卡欢迎关注公众号bigsai回复进群,如有帮助欢迎点赞支持! 移除元素 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长 ...
最新文章
- 安徽池州贵池中学老师经典语录,我喷了
- 腾讯业务监控的修炼之路
- Matlab读和写图像需要注意的问题
- hibernate 模糊查询及not in子查询
- 我们的合作伙伴Datawhale两岁啦!
- C语言 数字和字符串的转换 error
- linux技巧----查找某个正在执行的脚本
- 对象存储,为什么那么火?
- 笔记----Linux中pt_regs结构体
- java统计计数_java – 使用LongAdder计算统计计数器的最大值?
- JavaScript声明全局变量的三种方式
- linux centos8安装nginx_如何在 Fedora 30 Server 上安装 LEMP(Linux、Nginx、MariaDB、PHP)| Linux 中国...
- STM32中RTC唤醒停止模式
- Python数据去重
- 数量积与向量积(点积与叉积)
- YTU OJ 2476 Problem B C++习题 继承与组合
- 挂载NTFS分区导致Docker容器无法启动,Exited (137)错误
- leetcode 73 矩阵归零
- 西瓜书习题 - 8.集成学习
- Liunx userdel删除用户时提示userdel: user *** is currently used by process 12910
热门文章
- 这些年,职场上的奇葩领导--华山派
- 2023愚人杯-Comedy
- php 魔术方法 sleep,PHP 魔术方法: __sleep __wakeup
- 鬼谷算题1c语言,《鬼谷学校》谜题小测验,快来看看你能解锁几道题吧!
- 一.编写代码完成复制粘贴的功能
- [Linux][Colab] Colab连接google云盘 | ssh连接Colab | 防止Colab断连
- Cheat engine 下载安装及汉化
- 关于Diablo3的历史和现状思考
- 汇川中型PLC使用ST语言基础
- JAVA第九次作业《第11章-方法的重载-作业-计算工人工资》