找到三个最大值的最有效方法

时间:2010-02-09 23:00:03

标签: c++ performance max min

下面是我的伪代码。

function highest(i, j, k)
{
  if(i > j && i > k)
  {
    return i;
  }
  else if (j > k)
  {
    return j;
  }
  else
  {
    return k;
  }
}

我认为这有效,但这是C ++中最有效的方法吗?

14 个答案:

答案 0 :(得分:26)

要找到最好的,你需要正好看3个整数,不多也不少。你看6比较3。你应该能够在3和2比较中做到这一点。

int ret = max(i,j);
ret = max(ret, k);
return ret;

答案 1 :(得分:14)

伪代码:

result = i
if j > result:
  result = j
if k > result:
  result = k
return result

答案 2 :(得分:12)

怎么样

return i > j? (i > k? i: k): (j > k? j: k);

两次比较,不使用临时临时堆栈变量...

答案 3 :(得分:7)

您目前的方法: http://ideone.com/JZEqZTlj(0.40s)

Chris的解决方案:

int ret = max(i,j);
ret = max(ret, k);
return ret;

http://ideone.com/hlnl7QZX(0.39s)

Ignacio Vazquez-Abrams的解决方案:

result = i;
if (j > result)
  result = j;
if (k > result)
  result = k;
return result;

http://ideone.com/JKbtkgXi(0.40s)

查尔斯布雷塔纳:

return i > j? (i > k? i: k): (j > k? j: k);

http://ideone.com/kyl0SpUZ(0.40s)

在这些测试中,所有解决方案的执行时间都在3%之内。您尝试优化的代码非常短。即使你能够从中挤出1条指令,它也不可能在整个程序中产生巨大的差异(现代编译器可能会捕获那么小的优化)。把时间花在别处。

编辑:更新了测试,事实证明它仍在优化其中的部分内容。希望它不再存在。

答案 4 :(得分:5)

对于这样的问题,无法替代您只知道优化编译器正在做什么以及硬件上可用的内容。如果你拥有的基本工具是二元比较或二进制最大值,那么两个比较或最大值都是必要和充分的。

我更喜欢Ignacio的解决方案:

result = i;
if (j > result)
  result = j;
if (k > result)
  result = k;
return result;

因为在常见的现代英特尔硬件上,编译器会发现只发出两个比较和两个cmov指令非常容易,它们在I-cache上施加较小的负载,对分支预测器的压力小于条件分支。 (此外,代码清晰易读。)如果您使用的是x86-64,编译器甚至会将所有内容保存在寄存器中。

请注意,您很难将此代码嵌入到程序中,您的选择会有所不同......

答案 5 :(得分:4)

我喜欢消除条件跳跃作为一种智力锻炼。这是否对性能有任何可衡量的影响我不知道:)

#include <iostream>
#include <limits>

inline int max(int a, int b)
{
    int difference = a - b;
    int b_greater = difference >> std::numeric_limits<int>::digits;
    return a - (difference & b_greater);
}

int max(int a, int b, int c)
{
    return max(max(a, b), c);
}

int main()
{
    std::cout << max(1, 2, 3) << std::endl;
    std::cout << max(1, 3, 2) << std::endl;
    std::cout << max(2, 1, 3) << std::endl;
    std::cout << max(2, 3, 1) << std::endl;
    std::cout << max(3, 1, 2) << std::endl;
    std::cout << max(3, 2, 1) << std::endl;
}

这一点很有趣,cmov解决方案可能要快得多。

答案 6 :(得分:3)

不确定这是否最有效,但它可能是,并且它肯定更短:

int maximum = max( max(i, j), k);

答案 7 :(得分:1)

有人建议将其包含在N2485下的C ++库中。提案很简单,所以我在下面列出了有意义的代码。显然,这假定了可变参数模板

template < typename T >
const T & max ( const T & a )
{ return a ; }

template < typename T , typename ... Args >
const T & max( const T & a , const T & b , const Args &... args )
{ return  max ( b > a ? b : a , args ...); }

答案 8 :(得分:0)

public int maximum(int a,int b,int c){
    int max = a;
    if(b>max)
        max = b;
    if(c>max)
        max = c;
    return max;
}

答案 9 :(得分:0)

我认为&#34;效率最高&#34;你在谈论性能,尽量不浪费计算资源。但是你可能指的是编写更少的代码行,或者可能指的是源代码的可读性。我在下面提供一个示例,您可以评估您是否找到了有用的内容,或者您​​是否更喜欢您收到的答案中的其他版本。

/* Java version, whose syntax is very similar to C++. Call this program "LargestOfThreeNumbers.java" */
class LargestOfThreeNumbers{
    public static void main(String args[]){
        int x, y, z, largest;
        x = 1;
        y = 2;
        z = 3;
        largest = x;
        if(y > x){
            largest = y;
            if(z > y){
                largest = z;
            }
        }else if(z > x){
            largest = z;
        }
        System.out.println("The largest number is: " + largest);
    }
}

答案 10 :(得分:0)

#include<stdio.h>
int main()
{
    int a,b,c,d,e;
    scanf("%d %d %d",&a,&b,&c);
    d=(a+b+abs(a-b))/2;
    e=(d+c+abs(c-d))/2;
    printf("%d is Max\n",e);
    return 0;
}

答案 11 :(得分:-1)

最大的3个数字

int greater = a>b ? (a>c? a:c) :(b>c ? b:c); 
System.out.println(greater);

答案 12 :(得分:-1)

在c ++中查找最大或最小2个或更多数字的最简单方法是:-

int a = 3, b = 4, c = 5;
int maximum = max({a, b, c});

int a = 3, b = 4, c = 5;
int minimum = min({a, b, c});

您可以根据需要提供任意数量的变量。

足够有趣的是,它的效率也非常高,至少与Ignacio Vazquez-Abrams的解决方案(https://godbolt.org/z/j1KM97)一样有效:

        mov     eax, dword ptr [rsp + 8]
        mov     ecx, dword ptr [rsp + 4]
        cmp     eax, ecx
        cmovl   eax, ecx
        mov     ecx, dword ptr [rsp]
        cmp     eax, ecx
        cmovl   eax, ecx

与GCC类似,而MSVC使循环陷入混乱。

答案 13 :(得分:-1)

在C#中,找出3位数字之间的最大和最小数字

static void recorrectFindSmallestNumber()
{
int x = 30, y = 22, z = 11;
if (x < y)
{
if (x < z)
{
Console.WriteLine("X is Smaller Numebr {0}.", x);
}
else
{
Console.WriteLine("z is Smaller Numebr {0}.", z);
}
}
else if (x > y)
{
if (y < z)
{
Console.WriteLine("y is Smaller number.{0}", y);
}
else
{
Console.WriteLine("z is Smaller number.{0}", z);
}
}
 else
{

}
}

================================================ ==================

static void recorrectFindLargeNumber()
{
int x, y, z;
Console.WriteLine("Enter the first number:");
x = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the second number:");
y = int.Parse(Console.ReadLine());
Console.WriteLine("Enter the third nuumnber:");
z = int.Parse(Console.ReadLine());
if (x > y)
{
if (x > z)
{
Console.WriteLine("X is Greater numbaer: {0}.", x);
}
else
{
Console.WriteLine("Z is greatest number: {0}.", z);
}
}
else if (x < y)
{
if (y > z)
{
Console.WriteLine("y is Greater Number: {0}", y);
}
else 
{
Console.WriteLine("Z is Greater Number; {0}", z);                
}
}
else
{
                
}
}