不使用比较和条件判断实现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函数的一种方法的更多相关文章

  1. jQuery 判断checkbox是否被选中 4种方法

    下午写JS验证,有一个需求需要判断 checkbox是否被选择,查阅相关资料后,总结以下4种方法,分享给大家. <!DOCTYPE html> <html lang="en ...

  2. C#判断字符串为空的几种方法和效率判断

    C#判断字符串为空的几种方法和效率判断 string定义 1.1 string str1="":会定义指针(栈),并在内存里划一块值为空的存储空间(堆),指针指向这个空间.1.2 ...

  3. 如何通过PHP判断年份是否是闰年----两种方法

    1.定义:闰年是对4取余为0,对100取余不等于0,对400取余等于0的年是闰年. 2.代码: 第一种方法:直接函数判断 $day = date('Y'); if ($day%4==0&&am ...

  4. C# 判断字符串为空的4种方法及效率

    在程序开发过程中,少不了要处理字符串,并且常常要判断字符串是否为空,通常有哪些判断方法,以及不同方法的效率又怎么样? 在 C# 中,通常有三种判断字符串是否为空的方法,下面分别探讨. 1.str.Le ...

  5. js如何判断一个对象是不是Array? 三种方法总有一种可以帮上忙

    转载:http://www.nowamagic.net/librarys/veda/detail/1250 在开发中,我们经常需要判断某个对象是否为数组类型,在Js中检测对象类型的常见方法都有哪些呢? ...

  6. SSE图像算法优化系列十六:经典USM锐化中的分支判断语句SSE实现的几种方法尝试。

    分支判断的语句一般来说是不太适合进行SSE优化的,因为他会破坏代码的并行性,但是也不是所有的都是这样的,在合适的场景中运用SSE还是能对分支预测进行一定的优化的,我们这里以某一个算法的部分代码为例进行 ...

  7. iOS 判断网络连接状态的几种方法

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #801b80 } p.p2 ...

  8. PHP中判断变量为空的几种方法

    判断变量为空,在许多场合都会用到,同时自己和许多新手一样也经常会犯一些错误, 所以自己整理了一下PHP中一些常用的.判断变量为空的方法. 1. isset功能:判断变量是否被初始化本函数用来测试变量是 ...

  9. msyql判断记录是否存在的三种方法

    1. select count(*) from .... 这种方法最常见但是效率比较低,因为它需要扫描所有满足条件的记录 2. select 1 from xxxtable where .... 这种 ...

随机推荐

  1. 三、MyCat主要配置介绍

    一.配置文件 1.server.xml Mycat的配置文件,设置账号.参数等2.schema.xml Mycat对应的物理数据库和数据库表的配置3.rule.xml Mycat分片(分库分表)规则 ...

  2. 服务端处理 Watcher 实现 ?

    1.服务端接收 Watcher 并存储 接收到客户端请求,处理请求判断是否需要注册 Watcher,需要的话将数据节点 的节点路径和 ServerCnxn(ServerCnxn 代表一个客户端和服务端 ...

  3. Redis 集群的主从复制模型是怎样的?

    为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所 以集群使用了主从复制模型,每个节点都会有 N-1 个复制品.

  4. Vue的computed(计算属性)使用实例之TodoList

    最近倒腾了一会vue,有点迷惑其中methods与computed这两个属性的区别,所以试着写了TodoList这个demo,(好土掩面逃~); 1. methods methods类似react中组 ...

  5. AS之AlertDialog使用

    关于AlertDialog的使用,主要是去做一个弹窗. import android.content.DialogInterface; import android.os.Bundle; import ...

  6. 三种div点击事件

    <div id="div" onclick="alert('成功')">点击</div> var oDiv = document.get ...

  7. redis5.0.0集群搭建【实战经历】

    redis集群搭建 作者:陈土锋 时间:2020年6月2日 目录 一.环境介绍... 1 1.机器准备... 1 2.关闭防护墙和selinux. 1 3.时间同步... 1 二.Redis Clus ...

  8. Istio实践(1)-环境搭建及应用部署

    1. Istio简介 Istio是最初由IBM,Google和Lyft开发的服务网格的开源实现.它可以透明地分层到分布式应用程序上,并提供服务网格的所有优点,例如流量管理,安全性和可观察性. 它旨在与 ...

  9. 论文翻译:2021_Performance optimizations on deep noise suppression models

    论文地址:深度噪声抑制模型的性能优化 引用格式:Chee J, Braun S, Gopal V, et al. Performance optimizations on deep noise sup ...

  10. MySQL启动过程详解二:核心模块启动 init_server_components()

    mysqld_main() 函数中,init_server_components() 函数负责MySQL核心模块的启动,包括mdl系统,Innodb存储引擎的启动等等: 1. mdl子系统初始化. 2 ...