用于查找三个值中较大值和较小值的最有效算法



编辑:关于有人在读这篇文章的奇怪变化,我想补充最后一点。假设有问题的三个值已经在内存中,并且它们没有改变,我已经计算了不少于14条指令来实现这一壮举。

我非常喜欢这一点,如果有人可以的话。

[顶部编辑结束]

问题很简单。我有三个整数值,我需要找到最大的和最小的。我所说的"最大"指的不是最小或介于两者之间,反之亦然。

由于我无法在网上找到"高质量的解决方案",我不得不自己尝试。

if(a > b) {
  if(a > c) {
    high = a;
    if(b > c) {
      low = c;
    }
    else {
      low = b;
    }
  }
  else {
    if(b > c) {
      high = b;
      low = c;
    }
    else {
      high = c;
      low = b;
    }
  }
}
else if(a > c) {
  if(b > c) {
    high = b;
    low = c;
  }
  else {
    high = c;
    low = b;
  }
}
else {
  low = a;
  if(b > c) {
    high = b;
  }
  else {
    high = c;
  }
}

假设我没有犯任何错误,这应该使用三个条件句来解决问题。

假设它按预期工作,实际上我对我的努力很满意,但我的意图是找到最有效的算法,所以我现在问你那是什么

致以最良好的问候。

编辑:我已经审查了到目前为止提出的解决方案,它们都很好。

到目前为止我最喜欢的。

if(a>b) {
  max = a;
  min = b;
}
else {
  max = b;
  min = a;
}
if(c>max)
  max = c
else if(c< min)
  min = c

2-3个叹词和2-3个条件句,如果我没有弄错的话。令人印象深刻。

上面的小修订,使用"a"作为"min"的别名。

if(a>b) {
  max = a;
  a = b;
}
else {
  max = b;
}
if(c>max)
  max = c
else if(c< a)
  a = c

如果有一种简单的方法来交换变量就好了。。。好吧,我唯一能想到的是,这可以消除对"max"的需求,至少在C和C衍生物中,除了内存使用之外,肯定不会有效率,而且我可以多花4个字节。)

由于您只有3个,我会使用以下内容:

Maximum = max(a, max(b,c))
Minimum = min(a, min(b,c))

我不太确定你在用什么语言,但大多数每种语言都有一个max函数,内置或易于访问。

def min_max(a, b, c):
    if a > b:
        min, max = b, a   # two assignments
    else:
        min, max = a, b   # ditto
    if c > max:
        max = c
    elif c < min:
        min = c
    return (min, max)
if(a>b){swap(a,b);    /* in other words: a=a^b;b=a^b;a=a^b; */}
if(a>c){swap(a,c);    /*in other words: a=a^c;c=a^c;a=a^c;  */}
if(b>c){swap(b,c);    /*in other words: b=b^c;c=b^c;b=b^c;  */}
//now a is the smallest, c is the largest, but names are changed
high=c;
low=a;

如果你绝望了,

void swap(int & x, int & y)  //<--- yes it needs to be pass by reference
{
    __asm
    {
       movaps xmm5,[x]
       movaps xmm6,[y]   
       movaps [x],xmm6
       movaps [y],xmm5   //i cant say anything without trying ^^
    }
    return;
}

只有3个比较=更少的cpu错误分支预测和总循环指令将足够小,可以放入cpu循环缓存(decoded-inst.cache)

也许

 highest = a; lowest = a;
 if (b>a)
 {
     highest = b;
 }
 else
 {
     lowest = b;
 }
 if (c>highest)
 {
     highest = c;
 }
 else
 {
     if (c<lowest)
     {
         lowest = c;
     }
 }

这使用3个比较和3或4个赋值。

min = max = a;
if a < b
    max = b
else
    min = b
if b < c
    if c > a:
        max = c
else
    if c < a:
        min = c

此解决方案使用23之间的比较。

返回值为couple(最小值,最大值)。

  • 从3个给定的数字中选择2个
  • 将它们进行比较,并将较小的一个称为a,将较大的一个命名为b
  • 让我们拨打未选择的号码c
  • 如果c>=b,则返回(a,c)
  • 如果c>=a,则返回(a,b)
  • return(c,b)

计算/枚举开关应该给编译器足够的自由度来最小化(条件)跳跃的数量:

#include <stdio.h>
static inline void minmax3(int*themin,int*themax, int a, int b, int c)
{
switch(
          1 * (a>b)
        + 2 * (a>c)
        + 4 * (c>b)
        ) {
        case 0: *themin = a; *themax = b; break;
        case 1: *themin = b; *themax = a; break;
        case 2: *themin = c; *themax = b; break;
        case 3: *themin = b; *themax = a; break;
        case 4: *themin = a; *themax = c; break;
        case 5: *themin = b; *themax = c; break;
        case 6: *themin = b; *themax = c; break;
        case 7: *themin = b; *themax = a; break;
        }
return ;
}
int main(void)
{
int a,b,c,mi,ma;
for (a=0; a <3; a++) {
        for (b=0; b <3; b++) {
                for (c=0; c <3; c++) {
                        minmax3( &mi, &ma, a, b, c);
                        printf("a=%d b=%d c=%d min=%d max=%dn"
                        , a, b, c, mi, ma
                        );
        }}}
return 0;
}
if(a>=b)
 {if(a>=c)
   {MAX=a;
    MIN=c;
    if(c>=b)
     MIN=b;
     }
  else
   MAX=c,MIN=b;
 }
else
{if(b>=c)
   {MAX=b;
    MIN=c
    if(c>=a)
     MIN=a;
     }
  else
   MAX=c,MIN=a;
 }

最新更新