• 不使用条件判断和比较运算符来比较大小


    平时我们都是使用了比较运算符和条件判断, 来进行数字大小的比较, 但是有一些比较巧妙的方法, 也可以比较大小.

    查了一些资料, 之后, 发现了三种思路, 设两个数为a和b

    1. a - b的结果, 进行移位, 取符号位, 0说明结果是正数, a > b, 1说明结果是负数, a < b
    2. (a+b)/2 + |(a-b)/2| 或者 (a+b)/2 - |(a-b)/2| , 前者可以取得较大的值, 后者取得较小的值, 很容易数学上证明
    3. 分配一个长度为a的数组array[a], 判断array[b]是否越界, 越界在java中会抛出异常

    下面是用java实现的上述三种方法

    第一种的代码实现

    	/**
    	 * 比较符号位 0表示a>b, 1表示a<b
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static int compare(int a, int b) {
    		// >> 带符号的右移, >>> 无符号的右移
    //		return (((a - b) & 0x80000000) >> 31); // 判断符号位, a<b时为-1, 因为>>是带符号的右移, 保留了原来结果的符号位
    		return (((a - b) & 0x80000000) >>> 31); // 判断符号位
    	}
    

     第二种

    	/**
    	 * 返回a和b中较大的数
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static int compare(int a, int b) {
    		double x = (double)a;
    		double y = (double)b;
    		return (int)((x+y)/2 + Math.abs((x-y)/2)); // 判断符号位
    	}
    	
    	/**
    	 * 返回a和b中较小的数
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static int compare(int a, int b) {
    		double x = (double)a;
    		double y = (double)b;
    		return (int)((x+y)/2 - Math.abs((x-y)/2)); // 判断符号位
    	}
    

     第三种

    	/**
    	 * 通过数组越界来判断
    	 * @param a
    	 * @param b
    	 * @return
    	 */
    	public static int compare(int a, int b) {
    		int[] array = new int[a];
    		try {
    			array[b] = 0; // b>a的话, 会越界, 报异常
    		} catch (ArrayIndexOutOfBoundsException e) {
    			return b;
    		}
    		return a;
    	}
    

     三种方式的实现方法都很简单

    小结

    第一种可能是最差的一种, 只获得了一个谁大谁小的信息, 还需要用条件判断来返回最大最小值, 思路是好, 感觉不是特别好用.

    第二种数学方法还是比较好的, 可以取得最大最小值, 而且很简单, 第三种方法很巧妙, 也可以获得最大最小值.

    问题的延伸

    最近看到这样一个问题

         现给有一区间: $start - $end
         给定一变量: $param
         if $param < $start 则返回$param = $start
         if $param > $end 则返回$param = $end
         不用if else, 三元 等逻辑运算符
         实现此算法

    这个问题, 肯定需要不用条件和比较来比较两个数的大小,

    	/**
    	 * 现给有一区间: $start - $end
    	 * 一变量: $param
    	 * if $param < $start 则返回$param = $start
    	 * if $param > $end 则返回$param = $end
    	 * 不用if else, 三元 等逻辑运算符
    	 * 实现此算法
    	 */
    	public static int compare(int param, int start, int end) {
    		int[] array = new int[param];
    		try {
    			array[start] = 0; // param < start 越界异常
    		} catch (ArrayIndexOutOfBoundsException e) {
    			param = start;
    		}
    		
    		try {
    			array[end] = 0; // param > end 没有越界异常
    			param = end;
    		} catch (ArrayIndexOutOfBoundsException e) {
    		}
    		
    		return param;
    	}
    	
    	public static int compare(int param, int start, int end) {
    		double p = (double) param;
    		double s = (double) start;
    		double e = (double) end;
    		// p < s 返回较大值
    		p = (p+s)/2 + Math.abs((p-s)/2);
    		// p > e 返回较小值
    		p = (p+e)/2 - Math.abs((p-e)/2);
    		// s < p < e 返回p
    		return (int)p;
    	}
    

    这种问题可能会在笔试或面试的时候遇到, 平时还是要多积累, 多思考.

    由于笔者水平有限, 如果错漏, 欢迎指正!

    参考资料:

    1. 飝兒, 不用IF比较两数大小, 原文地址: http://www.haogongju.net/art/867439
  • 相关阅读:
    机器学习问题
    sklearn学习笔记
    机器学习之广义线性模型
    因子学习笔记、问题汇总
    数学相关知识汇总
    下载技巧汇总
    python scipy库
    20180122 PyTorch学习资料汇总
    机器学习基本概念笔记
    机械学习框架、分类
  • 原文地址:https://www.cnblogs.com/icejoywoo/p/2385338.html
Copyright © 2020-2023  润新知