计算 3 个整数的中间整数
Posted
技术标签:
【中文标题】计算 3 个整数的中间整数【英文标题】:Calculating middle int out of 3 ints 【发布时间】:2017-09-20 14:04:33 【问题描述】:对于计算 a、b 和 c 之间的中间 int,这 one-liner 是否正确?
注意: 我不想计算平均值,如果这 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;
【问题讨论】:
是...但很少进行测试... “代码有效” == codereview.stackexchange.com/tour 如果您正在寻找比您更好的解决方案,您必须查看这里***.com/questions/1582356/… 你的意思是“很少做测试”?有 6 种可能的顺序:a < b < c
、a < c < b
、b < a < c
、b < c < a
、c < a < b
、c < b < a
。如果所有这六种情况都有效,那么您的代码就可以了。
你说“我不想计算中位数......只是中间那个......”这几乎就是中位数的定义。
【参考方案1】:
我尝试了三个不同的选项,并计算了每个选项在 1,000,000 次迭代中所花费的时间
-
使用复三元
对 List 使用 Collections 排序方法
使用数学最小值和最大值
它们都给出相同的结果,但 2 和 3 几乎在零毫秒内执行
性能测试
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));
输出
Time Taken #1 -> 16
Time Taken #2 -> 71
Time Taken #3 -> 6
查看输出,就性能而言,选项 #3 是最好的。
三者之最
middle = Math.max(Math.min(a, b), Math.min(Math.max(a, b), c));
【讨论】:
您的“基准测试”仅测量计算的 1 次迭代,包括对System.out.println()
的调用。修复它,我将删除我的反对票。
更好,谢谢。尽管即使是 100 也太短了。试试十万? :-)
@JasonS 尝试了 100 万次迭代,这实际上突出了差异 :-) 感谢您的建议【参考方案2】:
这个单行是正确的吗?
让我们一步一步来:
return a <= b ? (c <= a ? a : c <= b ? c : b ) : c <= b ? b : c <= a ? c : a;
假设 a
现在假设 a a。现在如果 c b 和 b > a,所以我们将返回 a。请注意,您有一个额外的比较。 (我们已经知道 b > a,我们刚刚知道 c > b,这给了我们排序)
请注意有关此单行的两件事:虽然事实证明您的逻辑是正确的,但要确定其正确性既困难又耗时,而且它无法扩展(想象一下这个单行用于五个项目。 ..)
正确的做法是对列表进行排序,取中间项。
(这正是您所要求的:“如果这 3 个按从小到大的顺序排列,那就是中间那个。”)
【讨论】:
【参考方案3】:Math.max(Math.min(a, b), Math.min(Math.max(a, b), c));
适用于所有情况。
【讨论】:
虽然不能扩展。 [1, 6, 3, -1, 98, 2, 7] 的中位数呢? 我正在实现快速排序算法的轴心选择。从这个 POV 来看,没有必要,但非常感谢。 好的,所以如果你正在编写一个排序,那么你假设你没有排序 - 如果你知道你正在处理一个包含三个的列表,总是,这是一个更好的答案。 是的,至少三个。以上是关于计算 3 个整数的中间整数的主要内容,如果未能解决你的问题,请参考以下文章