首页 > 其他分享 >移位操作搞定两数之商

移位操作搞定两数之商

时间:2024-05-05 17:11:07浏览次数:22  
标签:搞定 之商 int math dividend quotient 231 两数 divisor

五一漫长的假期,外面的世界是人山人海,反而在家刷题算得上一个好的休闲方式。刚好我开始写这道题:

Given two integers `dividend` and `divisor`, divide two integers **without** using multiplication, division, and mod operator.

The integer division should truncate toward zero, which means losing its fractional part. For example, `8.345` would be truncated to `8`, and `-2.7335` would be truncated to `-2`.

Return *the **quotient** after dividing* `dividend` *by* `divisor`.

**Note:** Assume we are dealing with an environment that could only store integers within the **32-bit** signed integer range: `[−231, 231 − 1]`. For this problem, if the quotient is **strictly greater than** `231 - 1`, then return `231 - 1`, and if the quotient is **strictly less than** `-231`, then return `-231`.

 

**Example 1:**

Input: dividend = 10, divisor = 3
Output: 3
Explanation: 10/3 = 3.33333.. which is truncated to 3.


**Example 2:**

Input: dividend = 7, divisor = -3
Output: -2
Explanation: 7/-3 = -2.33333.. which is truncated to -2.


 

**Constraints:**

-   `-231 <= dividend, divisor <= 231 - 1`
-   `divisor != 0`

看懂题目上说的,就是不能用乘法、除法以及取余操作来算出两个给定整数的商。这个时候我想到利用移位操作来实现。
虽然工作多年,但是真正在实际项目中用到移位操作的时候是很少的。
逻辑移位:

-   逻辑移位将位向左或向右移动,并在空位填充零。
-   在左逻辑移位(<<)中,位向左移动,从右侧填充零。
-   在右逻辑移位(>>)中,位向右移动,从左侧填充零。

简单来说,如果1<<2, 就是1乘以2的2次方,以此类推。
所以我的解法就很明确了, 处理好被除数和除数的符号,然后再通过循环里面使用移位操作计算出商的:


func divide(dividend int, divisor int) int {
	quotient := 0
	maxInt := math.MaxInt32
	minInt := math.MinInt32
	if divisor == 0 || (dividend == minInt && divisor == -1) {
		return maxInt
	}

	// determine the sign of the quotient
	sign := -1
	if (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0) {
		sign = 1
	}

	// Convert the dividend and divisor to be positive number
	positiveDividend, positiveDivisor := int(math.Abs(float64(dividend))), int(math.Abs(float64(divisor)))

	for positiveDividend >= positiveDivisor {
		shift := 0
		for positiveDividend >= (positiveDivisor << shift) {
			shift += 1
		}

		quotient += (1<< (shift - 1))
		positiveDividend -= (positiveDivisor << (shift - 1))
	}
	
	return int(math.Min(float64(maxInt), math.Max(float64(sign) * float64(quotient), float64(minInt))))
}

总结

移位操作虽然好,但也不是唯一解,回忆一下小时候还没学乘法的时候,我们也可以用加法去模拟乘法,所以利用累加来模拟出两数之商更直观。
经过我的尝试,我发现完全减法会导致超时问题,不得不结合shifting操作,代码如下所示:


func divide(dividend int, divisor int) int {
	quotient := 0
	maxInt := math.MaxInt32
	minInt := math.MinInt32
	if divisor == 0 || (dividend == minInt && divisor == -1) {
		return maxInt
	}
	// determine the sign of the quotient
	sign := -1
	if (dividend ^ divisor) >= 0 {
		sign = 1
	}

	// Convert the dividend and divisor to be positive number
	positiveDividend, positiveDivisor := int(math.Abs(float64(dividend))), int(math.Abs(float64(divisor)))

	// Every time postiveDividend subtract with the value of the divisor
	for positiveDividend >= positiveDivisor {
		// Initialize variables for binary search
        tempDivisor := positiveDivisor
        multiple := 1
        
        // Perform binary search-like division
        for positiveDividend >= (tempDivisor << 1) {
            tempDivisor <<= 1
            multiple <<= 1
        }
        
        // Subtract the multiple of divisor from dividend
        positiveDividend -= tempDivisor
        // Add the multiple to quotient
        quotient += multiple
	}
	return int(math.Min(float64(maxInt), math.Max(float64(sign) * float64(quotient), float64(minInt))))
 }

标签:搞定,之商,int,math,dividend,quotient,231,两数,divisor
From: https://www.cnblogs.com/freephp/p/18173652

相关文章

  • 一次故障演练,十分钟自动搞定?
    本文分享自华为云社区《应用平台AppStage运维中心实践vol.4一次故障演练,十分钟自动搞定?》,作者:yangyang得意。某业务部涉及200+服务,部署架构复杂,各服务间依赖关系盘根错节,每次故障演练都需要耗费大量时间,还容易出现遗漏问题风险……有没有高效可靠的方法,可以在短时间内支撑......
  • ETL工具-nifi干货系列 第十六讲 nifi Process Group实战教程,一文轻松搞定
    1、目前nifi系列已经更新了10多篇教程了,跟着教程走的同学应该已经对nifi有了初步的解,但是我相信同学们应该有一个疑问:nifi设计好的数据流列表在哪里?如何同时运行多个数据流?如启停单个数据流?带着这些疑问,今天的主角nifiProcessGroup正式登场,先给大家看个图。2、ProcessGroup(......
  • 给定两个数x和y(长度相等),让它们可以交换各个位上的数字(位对应交换),求让两数乘积最大的
    如题,给出x=73,y=31,如何让两数乘积最大?位数定义:各个位上的数字例73,位数有7,3当前,只有一种交换策略,x=71,y=33,发现交换以后有:x+y=x'+y',如果抽象成求最大面积就好办了,可能一下想不到,还得多积累经验,不是你不知道是你想不到是你见得少,没见识...当是正方形的时候面积最大小学......
  • 两种解法搞定链表相邻节点交换
    最近还是很喜欢用golang来刷算法题,更接近通用算法,也没有像动态脚本语言那些语法糖,真正靠实力去解决问题。下面这道题很有趣,也是一道链表题目,具体如下:24.SwapNodesinPairsSolvedMediumTopicsCompaniesGivenalinkedlist,swapeverytwoadjacentnodesandreturni......
  • 3小时搞定DRF框架 | Django REST framework前后端分离框架实践
    DRF(全称DjangoRESTframework)是一个用于构建WebAPI的强力工具集,是一个基于Django的PythonWeb框架,它为开发人员提供了一套快速开发RESTfulAPI的工具,它能够自动化API可视化、文档化,实现接口的自动化测试以及自动化的API路由、序列化、视图、验证、分页、版本管理、认证等......
  • 想要获取抖音作者主页视频?一键获取轻松搞定!
    如今的社交媒体时代,短视频平台拥有无数用户的浏览。许多用户都希望能够获取到自己喜欢的作者主页上的视频,以便随时欣赏。然而,由于平台的严格限制等因素,普通用户往往难以直接获取到这些视频。不过,现在有了小编的帮助,小伙伴们可以轻松地获取到抖音作者主页上的视频,让观看体验更加......
  • Day5.一刷数据结构算法(C语言版) 242有效的字母异位词; 349两个数组的交集; 202快乐数; 1
        现在我们开始学习哈希表.        经过本次学习我认识到c++的便利,但是我使用的是c,那些功能c又用不了,导致代码长度一下子拉长了...        一刷的时候我还是先用c吧,等二刷的时候试试c++.        进入正题:        什么时候......
  • 一篇搞定!该喝什么水
    喝水,我们每天都要重复的行为,已经变得和呼吸、眨眼一样无比自然,不会引起太多的关注。水是承载我们生命的基础物质,没有水,人体就无法维持正常的运转。研究指出,人体大约由60%的水组成,水在我们体内扮演着多种重要角色,它可以调节人体的体温、维持细胞的正常代谢、运输养分和排废等等......
  • 两个专栏帮你搞定【图像拼接(image stitching)】
    【图像拼接论文精读】专栏:图像拼接论文精读【图像拼接源码精读】专栏:图像拼接论文源码精读前言图像拼接(imagestitching)是计算机视觉中的高级图像处理手段,是一个小众方向,研究的人很少,自然也没有人做这个领域的专栏教程。一方面,入门该邻域的难度大、门槛高,需要强大的数学、图形......
  • Android NDK之使用 arm-v7a 汇编实现两数之和
    AndroidNDK之使用arm-v7a汇编实现两数之和关键词:NDKarmv7aWebRTCarm汇编CMake最近适配对讲程序,在webrtc的库编译的过程中,发现其为arm的平台定制了汇编程序以优化平方根倒数算法速度,上次写汇编还是8086的,借此机会初步尝试下android上arm汇编具体jni工程建立就不介绍了,An......