栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java语法解析】不使用任何比较与选择判断,怎样输出a与b较大者?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java语法解析】不使用任何比较与选择判断,怎样输出a与b较大者?

文章目录

语法话题通过绝对值通过与运算通过移位运算


语法话题

本期的语法话题为:

两个int类型的变量a与b( a ≠ b a neq b a​=b):

    不允许使用任何比较运算符(例如>,<,?:等)。不允许使用任何选择判断语句(例如if,switch等)。不允许使用任何比较函数(例如max,min等)。

怎样输出a与b中的较大者?

这个问题也经常作为程序员的面试题被问到,当然,解决本问题的方式不止一种,我们现在就来给出几种不同的实现方式。


通过绝对值

我们知道, ∣ a − b ∣ |a - b| ∣a−b∣可以表示成如下的形式:

∣ a − b ∣ = { a − b a ⩾ b b − a a < b |a - b| = left{begin{matrix} a - b & a geqslant b \ b - a & a < b & \ end{matrix}right. ∣a−b∣={a−bb−a​a⩾ba

因此,我们就可以通过绝对值完成任务,如下:

a + b + ∣ a − b ∣ 2 frac{a + b + |a - b|}{2} 2a+b+∣a−b∣​

在Java中,程序如下:

package test;

public class Test {
	public static void main(String[] args) {
		int a = 2;
		int b = 3;
		int c = (a + b + Math.abs(a - b)) / 2;
		System.out.println(c);
	}
}

程序运行结果如下:

3

不过,通过绝对值的方式,严格来说并不算是正确的解决方案,因为在Java中,Math类的abs方法实现,也是通过?:运算符来判断的,源码如下:

    public static int abs(int a) {
        return (a < 0) ? -a : a;
    }

所以,如果遇到严格的面试官(比如梁老师^_^),这就不是一个最佳的解决方案。不过,我们依然可以通过其他方法来解决该问题。


通过与运算

对于int类型的变量,在内存中占用4个字节,也就是32位。int类型变量在内存中的存储格式为:

1个符号位 + 31个数据位

当变量存储的数值为非负数时,符号位为0,否则为1(变量存储数值为负数)。因此,我们可以通过符号位来判断变量a与b谁大。令c = a - b,则:

c = a − b ⇒ { c 的 符 号 位 为 0 ⇒ a − b ⩾ 0 ⇒ a 大 c 的 符 号 位 为 1 ⇒ a − b < 0 ⇒ b 大 c = a - b Rightarrow left{begin{matrix} c的符号位为0 & Rightarrow a - b geqslant 0 & Rightarrow a大 \ c的符号位为1 & Rightarrow a - b < 0 & Rightarrow b大 \ end{matrix}right. c=a−b⇒{c的符号位为0c的符号位为1​⇒a−b⩾0⇒a−b<0​⇒a大⇒b大​

可是,该如何获取变量c的符号位呢?通过与运算即可。
对于数据中的某个位(bit),设为x,有:

{ x & 1 = = x 保 留 x 位 的 信 息 x & 0 = = 0 清 理 x 位 的 信 息 left{begin{matrix} x & 1 == x & 保留x位的信息\ x & 0 == 0 & 清理x位的信息\ end{matrix}right. {x&1==xx&0==0​保留x位的信息清理x位的信息​

这样,我们就可以通过与运算,只保留符号位,而将其余31位(数据位)都清零,根据运算结果,就可以获取a与b的较大者,执行操作如下:

(a - b) & 0x8000_0000

如果运算结果为0(32个位都为0),则表示符号位为0,则a大。如果运算结果不为0(符号位为1,数据位都为0,此时为int类型的最小值-2147483648),则b大。

程序实现如下:

package test;

public class Test {
	public static void main(String[] args) {
		int a = 2;
		int b = 3;
		int c = (a - b) & 0x8000_0000;
		String result = c == 0 ? "a大,值为:" + a : "b大,值为:" + b;
		System.out.println(result);
	}
}

程序运行结果如下:

b大,值为:3

通过移位运算

这种方式与之前的与远算差不多,同样令c = a - b,然后对变量c进行无符号右移31位(只保留符号位),这样一来,c中的符号位就会成为数据位中的最后一位(最低位),其余31位高位都是0。

如果结果为0,则c的符号位为0,a大。如果结果为1,则c的符号位为1,b大。

这种实现,只需要把与运算程序中的第7行,修改成如下的方式即可:

		int c = (a - b) >>> 31;
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/776782.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号