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

2022/3/20 17:27:35

本文主要是介绍【Java语法解析】不使用任何比较与选择判断,怎样输出a与b较大者?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

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


语法话题

本期的语法话题为:

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

  1. 不允许使用任何比较运算符(例如>,<,?:等)。
  2. 不允许使用任何选择判断语句(例如if,switch等)。
  3. 不允许使用任何比较函数(例如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<b​​

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

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;


这篇关于【Java语法解析】不使用任何比较与选择判断,怎样输出a与b较大者?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程