Подтвердить что ты не робот

Самый эффективный способ найти самый большой из трех ints

Ниже мой псевдо-код.

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

Я думаю, что это работает, но является ли это самым эффективным способом в С++?

4b9b3361

Ответ 1

Чтобы найти самое большое, вам нужно посмотреть ровно 3 интервала, не более того. Вы смотрите на 6 с 3 сравнениями. Вы должны быть в состоянии сделать это в 3 и 2 сравнения.

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

Ответ 2

псевдокод:

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

Ответ 3

Как насчет

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

два сравнения, отсутствие временных переходных переменных стека...

Ответ 4

Ваш текущий метод: http://ideone.com/JZEqZTlj (0.40s)

Решение Криса:

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

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

Решение Игнасио Васкес-Абрамса:

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 инструкцию из нее, это вряд ли может иметь огромное значение во всей вашей программе (современные компиляторы могут поймать эту небольшую оптимизацию). Проведите время в другом месте.

РЕДАКТИРОВАТЬ: Обновлено тестирование, оказалось, что он все еще оптимизировал его части. Надеюсь, это уже не так.

Ответ 5

Для такого вопроса не существует замены для знания того, что делает ваш оптимизирующий компилятор, и того, что доступно на аппаратном уровне. Если основной инструмент, который у вас есть, - это двоичное сравнение или бинарный макс, то оба сравнения и максимум являются необходимыми и достаточными.

Я предпочитаю решение Игнасио:

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

потому что на общем современном оборудовании Intel компилятор будет очень легко испускать только два сравнения и две команды cmov, которые уменьшают нагрузку на I-кеш и уменьшают нагрузку на предсказатель ветвления, чем условные ветки, (Кроме того, код ясен и легко читается.) Если вы используете x86-64, компилятор даже сохранит все в регистрах.

Обратите внимание, что вам будет сложно вставить этот код в программу, где ваш выбор имеет значение...

Ответ 6

Мне нравится устранять условные прыжки как интеллектуальные упражнения. Имеет ли это какое-либо измеримое влияние на производительность, я понятия не имею:)

#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

Не уверен, является ли это наиболее эффективным или нет, но может быть, и это определенно короче:

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

Ответ 8

Есть предложение включить это в библиотеку С++ под N2485. Предложение прост, поэтому я включил осмысленный код ниже. Очевидно, это предполагает вариационные шаблоны

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

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

Я думаю, что "самым эффективным" вы говорите об эффективности, стараясь не тратить деньги на вычислительные ресурсы. Но вы можете ссылаться на написание меньшего количества строк кода или, возможно, на читаемость исходного кода. Ниже приведен пример, и вы можете оценить, находите ли вы что-то полезное или предпочитаете другую версию из полученных вами ответов.

/* 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

#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;
}

Ответ 12

Величайший из 3 номеров

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