不使用比较和条件判断实现min函数的一种方法
不使用比较和条件判断实现min函数,参数为两个32位无符号int。
面试的时候遇到的题目,感觉很有意思。
搜了一下多数现有的解法都是仅有两种限制之一,即要么仅要求不能使用比较,要么仅要求不能使用条件判断,于是打算写一下一种能兼顾两种限制的实现方法。
需要注意的是,条件判断当然也包含三目表达式、switch-case语句甚至abs等隐含条件分支的语法糖或标准库函数,除非能够不借助条件分支实现(例如没有条件分支的abs:参考链接)。
Solution
基本思想很简单,在二进制表示下从高位开始逐位比较,相同的位置可以直接忽略,直到遇到第一个不相同的位置,大小关系就决定了。譬如比较
a=011010
b=010110
时,从高位至低位比较到第三位时两数不同。此时必定是较大者 a 此位为 1,较小者 b 此位为 0,记此位为符号位 sign_a, sign_b。
实际上此时我们已经分辨出两数的大小,再想办法将较大者的信息抹掉即可。方法是分别将 a, b 剩余的每一位都与符号位相或,此时较大者 a 后半部分变为全 1,而较小者 b 不变,将两者相与,其结果等于 b,求得min。
在实际实现时可以使用位运算消除条件分支,具体可以参考代码。
"""
myMin(0b011010, 010110)
(1)
011010 A
010110 B
^ same 0 vs. 0
(2)
011010 A
010110 B
^ same 1 vs. 1
(3)
011010 A
010110 B
^ diff, sign_A=1, sign_B=0
(4)
011110 A'
010110 B'
^ A_i |= sign_A, B_i |= sign B
(5)(6)
011111 A''
010110 B''
^ A_i |= sign_A, B_i |= sign B
A'' & B'' = B
"""
def myMin(a, b):
found = 0
sign_a, sign_b = 0, 0
for i in range(32, -1, -1):
bit = 1 << i
xa, xb = (a & bit) >> i, (b & bit) >> i
# if not found:
# d = xa ^ xb
# else:
# d = 0
d = (not found) & (xa ^ xb)
# if xa ^ xb == 1:
# found = 1
found |= xa ^ xb
# if d:
# sign_a, sign_b = xa, xb
sign_a |= d & xa
sign_b |= d & xb
a |= sign_a * bit
b |= sign_b * bit
return a&b
# 用于生成随机测试用例测试正确性
import random, time
loop = 0
MAX = 1<<32
while True:
a, b = random.randint(0, MAX), random.randint(0, MAX)
if myMin(a, b) != min(a, b):
print(f"min({a}, {b}) = {min(a, b)} != {myMin(a, b)}")
break
loop += 1
print(loop, end='\r')
time.sleep(0.001)
不使用比较和条件判断实现min函数的一种方法的更多相关文章
- jQuery 判断checkbox是否被选中 4种方法
下午写JS验证,有一个需求需要判断 checkbox是否被选择,查阅相关资料后,总结以下4种方法,分享给大家. <!DOCTYPE html> <html lang="en ...
- C#判断字符串为空的几种方法和效率判断
C#判断字符串为空的几种方法和效率判断 string定义 1.1 string str1="":会定义指针(栈),并在内存里划一块值为空的存储空间(堆),指针指向这个空间.1.2 ...
- 如何通过PHP判断年份是否是闰年----两种方法
1.定义:闰年是对4取余为0,对100取余不等于0,对400取余等于0的年是闰年. 2.代码: 第一种方法:直接函数判断 $day = date('Y'); if ($day%4==0&&am ...
- C# 判断字符串为空的4种方法及效率
在程序开发过程中,少不了要处理字符串,并且常常要判断字符串是否为空,通常有哪些判断方法,以及不同方法的效率又怎么样? 在 C# 中,通常有三种判断字符串是否为空的方法,下面分别探讨. 1.str.Le ...
- js如何判断一个对象是不是Array? 三种方法总有一种可以帮上忙
转载:http://www.nowamagic.net/librarys/veda/detail/1250 在开发中,我们经常需要判断某个对象是否为数组类型,在Js中检测对象类型的常见方法都有哪些呢? ...
- SSE图像算法优化系列十六:经典USM锐化中的分支判断语句SSE实现的几种方法尝试。
分支判断的语句一般来说是不太适合进行SSE优化的,因为他会破坏代码的并行性,但是也不是所有的都是这样的,在合适的场景中运用SSE还是能对分支预测进行一定的优化的,我们这里以某一个算法的部分代码为例进行 ...
- iOS 判断网络连接状态的几种方法
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #801b80 } p.p2 ...
- PHP中判断变量为空的几种方法
判断变量为空,在许多场合都会用到,同时自己和许多新手一样也经常会犯一些错误, 所以自己整理了一下PHP中一些常用的.判断变量为空的方法. 1. isset功能:判断变量是否被初始化本函数用来测试变量是 ...
- msyql判断记录是否存在的三种方法
1. select count(*) from .... 这种方法最常见但是效率比较低,因为它需要扫描所有满足条件的记录 2. select 1 from xxxtable where .... 这种 ...
随机推荐
- ElasticSearch-学习笔记01-docker安装
安装ElasticSearch docker 安装请参考: https://www.cnblogs.com/youxiu326/p/docker-01.html docker run -d --nam ...
- 1、Jetson Nano 远程桌面XP问题
jeston nano上网 方法3(最简单的方法) 最简单的方法真的特简单,用USB数据线连接主板的USB接口以及手机,打开手机的USB共享即可,若要使用静态IP,可在主板上修改配置文件,接口一般为u ...
- 无单位数字和行高 —— 别说你懂CSS相对单位
前段时间试译了Keith J.Grant的CSS好书<CSS in Depth>,其中的第二章<Working with relative units>,书中对relative ...
- 7步学会在Windows下上架iOS APP流程
之前用跨平台开发工具做了一个应用,平台可以同时生成安卓版和苹果版,想着也把这应用上架到App Store试试,于是找同学借了个苹果开发者账号,但没那么简单,还要用到Mac电脑的钥匙串申请发布证书和上传 ...
- Py的A+B
程序会读入两行,每行都是一个数字,输出这两个数字的和 输入格式: 两行文字,每行都是一个数字 输出格式: 一行数字 输入样例: 18 21 输出样例: 39 代码: a = input() b = i ...
- 小程序申请测试appid
话不多说,直接上图: 1. 登录微信官方文档: https://developers.weixin.qq.com/miniprogram/dev/devtools/sandbox.html 2. ...
- Centos搭建 Docker 环境
搭建 Docker 环境 安装与配置 Docker 安装 Docker Docker 软件包已经包括在默认的 CentOS-Extras 软件源里.因此想要安装 docker,只需要运行下面的 yum ...
- Django实现统一包装接口返回值数据格式
前言 最近实在太忙了,开始了一个新的项目,为了快速形成产品,我选择了Django来实现后端,然后又拿起了之前我封装了项目脚手架「DjangoStarter」. 由于前段时间我写了不少.NetCore的 ...
- Python入门-分支循环结构
编写代码的过程中,除了基本的变量,数据类型,在实际开发中,大量代码是根据判断条件,进而选择不同的的向前运行方式. 这些向前的运行方式基本分为两种:分支结构,循环结构 1.分支结构 if单分支结构 # ...
- 第一阶段:Java基础之数组
注意点: @Java语言是把数组当作一个"对象"来看待的 @把数组分为两部分看,一部分是数组的引用,放置在栈内存中,一部分是数组对象,放置在堆内存中 @数组的引用可以指向任何有效的 ...