Java 找到三元组中间值的最快方法?
给定的是一个由三个数值组成的数组,我想知道这三个数值的中间值 问题是,找到三者中间位置的最快方法是什么 我的方法是这种模式——因为有三个数字,所以有六种排列:Java 找到三元组中间值的最快方法?,java,algorithm,conditional,logic,median,Java,Algorithm,Conditional,Logic,Median,给定的是一个由三个数值组成的数组,我想知道这三个数值的中间值 问题是,找到三者中间位置的最快方法是什么 我的方法是这种模式——因为有三个数字,所以有六种排列: if (array[randomIndexA] >= array[randomIndexB] && array[randomIndexB] >= array[randomIndexC]) 如果有人能帮我找到一种更优雅、更快捷的方法,那就太好了。以下是仅使用条件表达的方法: int a, b, c =
if (array[randomIndexA] >= array[randomIndexB] &&
array[randomIndexB] >= array[randomIndexC])
如果有人能帮我找到一种更优雅、更快捷的方法,那就太好了。以下是仅使用条件表达的方法:
int a, b, c = ...
int middle = (a <= b)
? ((b <= c) ? b : ((a < c) ? c : a))
: ((a <= c) ? a : ((b < c) ? c : b));
inta,b,c=。。。
int middle=(a在ary中使用idxA到idxC
int ab = ary[idxA] < ary[idxB] ? idxA : idxB;
int bc = ary[idxB] < ary[idxC] ? idxB : idxC;
int ac = ary[idxA] < ary[idxC] ? idxA : idxC;
int idxMid = ab == bc ? ac : ab == ac ? bc : ab;
intab=ary[idxA]
indexMiddle指向中间值
说明:从3个最小值中,2是总体最小值,另一个值必须是中间值。因为我们检查了相等性,所以可以比较最后一行中的索引,而不必比较数组值。或一个用于在包含中间值的数组中查找索引的一行:
int middleIndex = (a[0]<a[1]) ? ((a[0]<a[2) ? a[2] : a[0]) : ((a[1]<a[2) ? a[2] : a[1]);
int middleIndex=(a[0]如果您正在寻找最有效的解决方案,我可以想象它是这样的:
if (array[randomIndexA] > array[randomIndexB]) {
if (array[randomIndexB] > array[randomIndexC]) {
return "b is the middle value";
} else if (array[randomIndexA] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "a is the middle value";
}
} else {
if (array[randomIndexA] > array[randomIndexC]) {
return "a is the middle value";
} else if (array[randomIndexB] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "b is the middle value";
}
}
max(a,b)=(a+b+|a-b|)/2
min(a,b)=(a+b-|a-b|)/2
private static long median(Integer i1, Integer i2, Integer i3) {
List<Integer> list = Arrays.asList(
i1 == null ? 0 : i1,
i2 == null ? 0 : i2,
i3 == null ? 0 : i3);
Collections.sort(list);
return list.get(1);
}
这种方法需要至少两次,最多三次比较。它故意忽略两个值相等的可能性(就像你的问题一样):如果这很重要,可以扩展方法来检查这一点。如果必须从X个值中找到一个满足某些标准,则必须至少将该值与X-1其他值中的每个值进行比较。对于三个值,这意味着至少两次比较。因为这是“查找非最小值和非最大值”你只需要做两次比较就可以成功
然后,您应该集中精力编写代码,以便能够非常清楚地看到发生了什么,并保持简单。这里的意思是嵌套if。这将允许JVM在运行时尽可能地优化此比较
请参阅Tim()提供的解决方案看一个例子。许多代码行不一定比嵌套问号colon的代码大。你最好用最简单的方式来写。正如你所说,只有六种可能。没有合理的方法会更快或更慢,所以只需要简单易读。
为了简洁起见,我会使用min()和max(),但我认为三个嵌套的if/thens也一样好。这最多可以通过两个比较来完成
int median(int a, int b, int c) {
if ( (a - b) * (c - a) >= 0 ) // a >= b and a <= c OR a <= b and a >= c
return a;
else if ( (b - a) * (c - b) >= 0 ) // b >= a and b <= c OR b <= a and b >= c
return b;
else
return c;
}
整数中值(整数a、整数b、整数c){
如果((a-b)*(c-a)>=0)//a>=b和a=0)//b>=a和b如果硬件能够在没有分支的情况下回答最小和最大查询,那么就有可能在没有分支的情况下回答查询(今天的大多数CPU都可以这样做)
运算符^表示按位异或
Input: triple (a,b,c)
1. mx=max(max(a,b),c)
2. mn=min(min(a,b),c)
3. md=a^b^c^mx^mn
4. return md
这是正确的,因为:
- 异或是交换的和结合的
- 相等位上的异或产生零
- 带零的异或不改变位
应为int/float选择适当的min/max函数。
如果只存在正浮点,则可以直接在浮点表示上使用整数min/max(这可能是可取的,因为整数运算通常更快)
在硬件不支持最小/最大的不太可能的情况下,可以执行以下操作:
if (array[randomIndexA] > array[randomIndexB]) {
if (array[randomIndexB] > array[randomIndexC]) {
return "b is the middle value";
} else if (array[randomIndexA] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "a is the middle value";
}
} else {
if (array[randomIndexA] > array[randomIndexC]) {
return "a is the middle value";
} else if (array[randomIndexB] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "b is the middle value";
}
}
max(a,b)=(a+b+|a-b|)/2
min(a,b)=(a+b-|a-b|)/2
private static long median(Integer i1, Integer i2, Integer i3) {
List<Integer> list = Arrays.asList(
i1 == null ? 0 : i1,
i2 == null ? 0 : i2,
i3 == null ? 0 : i3);
Collections.sort(list);
return list.get(1);
}
但是,当使用浮点操作时,这是不正确的,因为需要精确的最小值/最大值,而不是接近它的值。幸运的是,浮点最小值/最大值在硬件中已经支持了很长时间(在x86上,从奔腾III开始)了。这一个可以工作:
template<typename T> T median3_1_gt_2(const T& t1, const T& t2, const T& t3) {
if (t3>t1) {
return t1;
} else {
return std::max(t2, t3);
}
}
template<typename T> T median3(const T& t1, const T& t2, const T& t3) {
if (t1>t2) {
return median3_1_gt_2(t1, t2, t3);
} else {
return median3_1_gt_2(t2, t1, t3);
}
}
模板T介质3\u 1\u gt\u 2(常数T&t1、常数T&t2、常数T&t3){
如果(t3>t1){
返回t1;
}否则{
返回标准::最大值(t2,t3);
}
}
模板T中间层3(常数T&t1、常数T&t2、常数T&t3){
如果(t1>t2){
返回介质3_1_gt_2(t1、t2、t3);
}否则{
返回介质3_1_gt_2(t2、t1、t3);
}
}
if(数组[aIndex]>数组[bIndex]){
if(array[bIndex]>array[cIndex])返回bIndex;
if(array[aIndex]>array[cIndex])返回cIndex;
返回aIndex;
}否则{
if(array[bIndex]
这里有一个答案,使用min/max和no分支()。实际上,4个min/max操作就足以找到中间值,不需要xor:
median = max(min(a,b), min(max(a,b),c));
虽然,它不会给你中值的指数
所有个案的分项数字:
a b c
1 2 3 max(min(1,2), min(max(1,2),3)) = max(1, min(2,3)) = max(1, 2) = 2
1 3 2 max(min(1,3), min(max(1,3),2)) = max(1, min(3,2)) = max(1, 2) = 2
2 1 3 max(min(2,1), min(max(2,1),3)) = max(1, min(2,3)) = max(1, 2) = 2
2 3 1 max(min(2,3), min(max(2,3),1)) = max(2, min(3,1)) = max(2, 1) = 2
3 1 2 max(min(3,1), min(max(3,1),2)) = max(1, min(3,2)) = max(1, 2) = 2
3 2 1 max(min(3,2), min(max(3,2),1)) = max(2, min(3,1)) = max(2, 1) = 2
还有一个想法。有三个数字{a,b,c}
。然后:
middle = (a + b + c) - min(a,b,c) - max(a,b,c);
当然,我们必须记住数字限制…您可以使用数组,如下所示:
if (array[randomIndexA] > array[randomIndexB]) {
if (array[randomIndexB] > array[randomIndexC]) {
return "b is the middle value";
} else if (array[randomIndexA] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "a is the middle value";
}
} else {
if (array[randomIndexA] > array[randomIndexC]) {
return "a is the middle value";
} else if (array[randomIndexB] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "b is the middle value";
}
}
max(a,b)=(a+b+|a-b|)/2
min(a,b)=(a+b-|a-b|)/2
private static long median(Integer i1, Integer i2, Integer i3) {
List<Integer> list = Arrays.asList(
i1 == null ? 0 : i1,
i2 == null ? 0 : i2,
i3 == null ? 0 : i3);
Collections.sort(list);
return list.get(1);
}
私有静态长中位数(整数i1、整数i2、整数i3){
List=Arrays.asList(
i1==null?0:i1,
i2==null?0:i2,
i3==null?0:i3);
集合。排序(列表);
返回列表。获取(1);
}
基于Gyorgy的优秀答案,您可以通过使用条件移动替换最小/最大值来获得无分支的中值指数:
int i = (array[A] >= array[B]) ? A : B;
int j = (array[A] <= array[B]) ? A : B;
int k = (array[i] <= array[C]) ? i : C;
int median_idx = (array[j] >= array[k]) ? j : k;
inti=(数组[A]>=array[B])?A:B;
int j=(数组[A]中值=(A+b+c)-Math.min(Math.min(A,b),c)-Math.max(Math.max(A,b),c)
这是最基本的一个,我不知道它的效率有多高,但这些函数毕竟使用if条件。如果您愿意,可以将此语句转换为if-else语句,但这需要时间。为什么这么懒?我没有看到实现交换的解决方案:
int middle(int a, int b, int c) {
// effectively sort the values a, b & c
// putting smallest in a, median in b, largest in c
int t;
if (a > b) {
// swap a & b
t = a;
a = b;
b = t;
}
if (b > c) {
// swap b & c
t = b;
b = c;
c = t;
if (a > b) {
// swap a & b
t = a;
a = b;
b = t;
}
}
// b always contains the median value
return b;
}
maximust=(a>b)和&(a>c)?a:(b>c?b:c);
最小值=(a方法1
int a,b,c,result;
printf("enter three number");
scanf("%d%d%d",&a,&b,&c);
result=a>b?(c>a?a:(b>c?b:c)):(c>b?b:(a>c?a:c));
printf("middle %d",result);
方法2
int a=10,b=11,c=12;
//Checking for a is middle number or not
if( b>a && a>c || c>a && a>b )
{
printf("a is middle number");
}
//Checking for b is middle number or not
if( a>b && b>c || c>b && b>a )
{
printf("b is middle number");
}
//Checking for c is middle number or not
if( a>c && c>b || b>c && c>a )
{
printf("c is middle number");
}
方法3
if(a>b)
{
if(b>c)
{
printf("b is middle one");
}
else if(c>a)
{
printf("a is middle one");
}
else
{
printf("c is middle one");
}
}
else
{
if(b<c)
{
printf("b is middle one");
}
else if(c<a)
{
printf("a is middle one");
}
else
{
printf("c is middle one");
}
}
if(a>b)
{
如果(b>c)
{
printf(“b是中间的一个”);
}
如果(c>a),则为else
{
printf(“a是中间的一个”);
}
其他的
{
printf(“c是中间的
int min(const int a, const int b) { const int d = b - a; return a + (d & (d >> 31)); }
int max(const int a, const int b) { const int d = a - b; return a - (d & (d >> 31)); }
int median2(int a, int b, int c) {
return (a > b) ^ (a > c) ? a : (a > b) ^ (b > c) ? c : b;
}
public static void main(String[] args) {
System.out.println(median(3, 6, 9));
System.out.println(median(3, 9, 6));
System.out.println(median(6, 3, 9));
System.out.println(median(6, 9, 3));
System.out.println(median(9, 3, 6));
System.out.println(median(9, 6, 3));
System.out.println(median(6, 6, 3));
System.out.println(median(6, 6, 9));
System.out.println(median(6, 3, 6));
System.out.println(median(6, 9, 6));
System.out.println(median(3, 6, 6));
System.out.println(median(9, 6, 6));
System.out.println(median(6, 6, 6));
}
| 00 01 11 10 (p, q)
---+----------------------
0 | b c * a
1 | * a b c
(s)|
| 0 1 (t)
---+---------
0 | b c
1 | * a
(u)|
private static int median(int a, int b, int c) {
boolean t = (a > b) ^ (b > c);
boolean u = (a > b) ^ (a > c);
if (u)
return a;
else if (t)
return c;
else
return b;
}
int median2(int a, int b, int c) {
return (a > b) ^ (a > c) ? a : (a > b) ^ (b > c) ? c : b;
}
// Compute median of three values, no branches
int median3(int V[3])
{
unsigned int A,B,C;
A=(V[0] < V[1]);
B=(V[1] < V[2]);
C=(V[0] < V[2]);
return V[(B^C)<<1 | (A^B^1)];
}
int middle(int A, int B, int C) {
return (A>B&&A>C)?B>C?B:C:(B>C&&B>A)?A>C?A:C:B;
}