14

下面是我的伪代码。

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

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

4

13 回答 13

28

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

int ret = max(i,j);
ret = max(ret, k);
return ret;
于 2010-02-09T23:02:36.963 回答
16

伪代码:

result = i
if j > result:
  result = j
if k > result:
  result = k
return result
于 2010-02-09T23:04:38.363 回答
13

怎么样

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

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

于 2010-02-09T23:13:27.147 回答
8

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

克里斯的解决方案:

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 条指令,也不太可能在整个程序中产生巨大的差异(现代编译器可能会抓住那个小优化)。把时间花在别处。

编辑:更新了测试,原来它仍然在优化它的一部分。希望不再是了。

于 2010-02-09T23:49:31.957 回答
6

对于这样的问题,只有知道优化编译器在做什么以及硬件上有什么可用,没有什么可替代的。如果您拥有的基本工具是二进制比较或二进制最大值,那么两次比较或最大值都是必要且足够的。

我更喜欢 Ignacio 的解决方案:

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

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

请注意,您将很难将此代码嵌入到您的选择会产生影响的程序中......

于 2010-02-10T00:13:36.270 回答
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解决方案可能要快得多。

于 2010-02-10T00:13:46.273 回答
3

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

int maximum = max( max(i, j), k);
于 2010-02-09T23:53:13.327 回答
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 ...); }
于 2017-01-19T23:56:23.387 回答
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;
}
于 2013-08-14T20:17:17.637 回答
0

我认为“最有效”是指性能,尽量不浪费计算资源。但是您可能指的是编写更少的代码行,或者可能是关于源代码的可读性。我在下面提供了一个示例,您可以评估是否发现有用的东西,或者您是否更喜欢收到的答案中的另一个版本。

/* 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);
    }
}
于 2018-01-23T12:59:19.287 回答
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;
}
于 2019-06-09T17:59:17.830 回答
0

在 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 使循环变得混乱。

于 2020-08-06T21:47:34.617 回答
-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
{
                
}
}
于 2020-09-13T15:40:34.603 回答