代码之家  ›  专栏  ›  技术社区  ›  Stephano

找到三个整数中最大的一个最有效的方法

  •  11
  • Stephano  · 技术社区  · 16 年前

    下面是我的伪代码。

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

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

    11 回复  |  直到 7 年前
        1
  •  26
  •   Chris H    16 年前

    要想找到最棒的,你需要精确地看3个音,不多不少。你看的是6比3。你应该能够在3和2的比较中做到这一点。

    int ret = max(i,j);
    ret = max(ret, k);
    return ret;
    
        2
  •  14
  •   Ignacio Vazquez-Abrams    16 年前

    Pseudocode:

    result = i
    if j > result:
      result = j
    if k > result:
      result = k
    return result
    
        3
  •  12
  •   Charles Bretana    16 年前

    怎么样

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

    两个比较,不使用临时堆栈变量…

        4
  •  7
  •   Ponkadoodle    16 年前

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

    克里斯的解决方案:

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

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

    Ignacio Vazquez Abrams的解决方案:

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

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

    查尔斯·布雷塔纳的:

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

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

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

    编辑: 更新了测试,结果发现之前它仍然在优化部分测试。希望不会再这样了。

        5
  •  5
  •   Norman Ramsey    16 年前

    对于这样的问题, 除了知道你的优化编译器在做什么以及硬件上有什么可用性之外,没有什么可以替代的。 . 如果您所拥有的基本工具是二进制比较或二进制最大值,则两个比较或最大值都是必要的和足够的。

    我更喜欢伊格纳西奥的解决方案:

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

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

    注意,很难将此代码嵌入到 程序 你的选择会带来不同…

        6
  •  4
  •   fredoverflow    16 年前

    我喜欢把有条件跳跃作为一种智力练习来消除。我不知道这是否对绩效有什么可测量的影响:)

    #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 解决方案可能要快得多。

        7
  •  3
  •   Scott Smith    16 年前

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

    int maximum = max( max(i, j), k);
    
        8
  •  1
  •   Sam Mokari    9 年前

    有一个建议把这个包含在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 ...); }
    
        9
  •  0
  •   user2683924    12 年前
    public int maximum(int a,int b,int c){
        int max = a;
        if(b>max)
            max = b;
        if(c>max)
            max = c;
        return max;
    }
    
        10
  •  0
  •   Jaime Montoya    8 年前

    我认为,通过“最有效的”方式,你在谈论性能,而不是浪费计算资源。但是,您可能指的是编写更少的代码行,或者您的源代码的可读性。我在下面提供一个例子,你可以评估你是否找到有用的东西,或者你是否更喜欢从你收到的答案中得到另一个版本。

    /* 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);
        }
    }
    
        11
  •  -1
  •   phuclv    7 年前

    3个数字中最大的

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