从3个整数中计算中间int

时间:2017-04-24 02:18:20

标签: java math

这个单行是否正确用于计算a,b和c之间的中间int?

  

注意: 我不想计算平均值,只计算中间的那个,如果这3个是从最小的到   最大(中位数)。

示例: 1 77 34 的中间值 34

public static int midpoint(int a, int b, int c) {

    return a <= b ? (c <= a ? a : c <= b ? c : b ) : c <= b ? b : c <= a ? c : a;
}

3 个答案:

答案 0 :(得分:3)

我尝试了三种不同的选项,并计算了每个选项在1,000,000次迭代中所花费的时间

  1. 使用复杂的三元
  2. 使用集合排序方法与列表
  3. 使用Math min和max
  4. 所有这些都给出相同的结果,但是2和3几乎在零毫秒内执行

    效果测试

    do {
            let matches = try context.fetch(request)
    let mention = matches.first
            if matches.count > 0 {
                mention?.count = (mention?.count)! + 1
    //.. more code
    

    输出

    int iterationCount = 1000000; // 1 million iterations
            Long t1 = Calendar.getInstance().getTimeInMillis();
            for (int i = 0; i < iterationCount; i++) {
                middle = a <= b ? (c <= a ? a : c <= b ? c : b) : c <= b ? b : c <= a ? c : a;
            }
            Long t2 = Calendar.getInstance().getTimeInMillis();
    
    
            // #2 Using Collection + List + Sort
            Long t3 = Calendar.getInstance().getTimeInMillis();
            for (int i = 0; i < iterationCount; i++) {
                List<Integer> list = Arrays.asList(a, b, c);
                Collections.sort(list);
                middle = list.get(1);
            }
            Long t4 = Calendar.getInstance().getTimeInMillis();
    
            // #3Using Math's min and max
            Long t5 = Calendar.getInstance().getTimeInMillis();
            for (int i = 0; i < iterationCount; i++) {
                middle = Math.max(Math.min(a, b), Math.min(Math.max(a, b), c));
            }
            Long t6 = Calendar.getInstance().getTimeInMillis();
    
            System.out.println("Time Taken #1 -> " + (t2 - t1));
            System.out.println("Time Taken #2 -> " + (t4 - t3));
            System.out.println("Time Taken #3 -> " + (t6 - t5));
    

    在输出中,选项#3在性能方面是最好的。

    最好的三个

    Time Taken #1 -> 16
    Time Taken #2 -> 71
    Time Taken #3 -> 6
    

答案 1 :(得分:1)

  

这个单行是否正确?

让我们一步一步:

return a <= b ? (c <= a ? a : c <= b ? c : b ) : c <= b ? b : c <= a ? c : a;

假设a&lt; = b。然后,如果c <= a,则返回a。因此,c&lt; = a&lt; = b和a是正确的返回。另一方面,如果c <= b,则c <= b <1。 a(b / c我们知道c&lt; = a不是真的)。所以,b适合返回。

现在假设&lt; = b为假 - 然后b&gt;一个。现在如果c&lt; = b,我们有c&lt; = b&lt; a,所以b是正确的。如果c <= b是假的,那么我们有c> b和b>我们将返回一个。请注意,您有一个额外的比较。 (我们已经知道b> a了,我们刚刚得知c> b,这给了我们订购)

注意关于这个单行的两件事:虽然事实证明你的逻辑是正确的,但确定正确性是困难和耗时的,并且它没有规模(想象这个单行为五项目...)

正确的方法是对列表进行排序并获取中间项。

(这正是你所要求的:&#34;如果这3个从最小到最大的顺序排在中间,那就是中间的那个。&#34;)

答案 2 :(得分:0)

Math.max(Math.min(a, b), Math.min(Math.max(a, b), c));

适用于所有情况。