The first你应该做的就是决定你的函数的用途。它的签名和名称表明它应该是return中位数,但实际上是代码prints它(并且,如果它只是打印它,它可能应该有一个void
返回类型)。
打印可能最好留给调用者,让函数只计算并返回中值。这使得它成为一个更加通用的函数。
无论如何,这是使用>
而不是>=
这导致了你的问题,因为两个或多个数字相同的数据集往往不会导致任何结果if
陈述属实。
一个“更干净”的解决方案(在我看来)就是依次涵盖所有六种可能性:
int median (int a, int b, int c) {
if ((a <= b) && (b <= c)) return b; // a b c
if ((a <= c) && (c <= b)) return c; // a c b
if ((b <= a) && (a <= c)) return a; // b a c
if ((b <= c) && (c <= a)) return c; // b c a
if ((c <= a) && (a <= b)) return a; // c a b
return b; // c b a
}
请注意,我已经使用过<=
在这里,只是因为它使条件与注释中显示的序列更加紧密地结合在一起。重要的是使用包含比较运算符,无论>=
or <=
,而不是像这样的专有的>
.
您甚至可以重构比较,使代码更具可读性,例如:
static int is_ordered(int x, int y, int z) {
return (x <= y) && (y <= z);
}
int median (int a, int b, int c) {
if (is_ordered(a, b, c)) return b;
if (is_ordered(a, c, b)) return c;
if (is_ordered(b, a, c)) return a;
if (is_ordered(b, c, a)) return c;
if (is_ordered(c, a, b)) return a;
return b; // Only one left is c, b, a.
}
我最初不会担心这里涉及的额外函数调用,除非你想多次调用它,many每秒次数。即使如此,您可能会发现编译器足够聪明,可以内联该函数。我的一般建议是首先优化可读性,then仅当性能成为问题时才担心它。
当然,还有另一种选择(几乎总是有)。
由于只有三个值,因此对它们进行排序并返回中间的值是一件简单的事情。它不必是复杂的排序,因为您只需使用由几个条件创建的展开的冒泡排序即可。执行此操作的代码如下所示:
int median (int a, int b, int c) {
// Unrolled bubble sort, then return middle one.
if (a > b) { int t = a; a = b; b = t; }
if (b > c) { int t = b; b = c; c = t; }
if (a > b) { int t = a; a = b; b = t; }
return b;
}
就我个人而言,我认为这不如之前的代码那么可读,但是,如果您喜欢它,它肯定是有用的。