Ниже мой псевдо-код.
function highest(i, j, k)
{
if(i > j && i > k)
{
return i;
}
else if (j > k)
{
return j;
}
else
{
return k;
}
}
Я думаю, что это работает, но является ли это самым эффективным способом в С++?
Ниже мой псевдо-код.
function highest(i, j, k)
{
if(i > j && i > k)
{
return i;
}
else if (j > k)
{
return j;
}
else
{
return k;
}
}
Я думаю, что это работает, но является ли это самым эффективным способом в С++?
Чтобы найти самое большое, вам нужно посмотреть ровно 3 интервала, не более того. Вы смотрите на 6 с 3 сравнениями. Вы должны быть в состоянии сделать это в 3 и 2 сравнения.
int ret = max(i,j);
ret = max(ret, k);
return ret;
псевдокод:
result = i
if j > result:
result = j
if k > result:
result = k
return result
Как насчет
return i > j? (i > k? i: k): (j > k? j: k);
два сравнения, отсутствие временных переходных переменных стека...
Ваш текущий метод: 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 инструкцию из нее, это вряд ли может иметь огромное значение во всей вашей программе (современные компиляторы могут поймать эту небольшую оптимизацию). Проведите время в другом месте.
РЕДАКТИРОВАТЬ: Обновлено тестирование, оказалось, что он все еще оптимизировал его части. Надеюсь, это уже не так.
Для такого вопроса не существует замены для знания того, что делает ваш оптимизирующий компилятор, и того, что доступно на аппаратном уровне. Если основной инструмент, который у вас есть, - это двоичное сравнение или бинарный макс, то оба сравнения и максимум являются необходимыми и достаточными.
Я предпочитаю решение Игнасио:
result = i;
if (j > result)
result = j;
if (k > result)
result = k;
return result;
потому что на общем современном оборудовании Intel компилятор будет очень легко испускать только два сравнения и две команды cmov
, которые уменьшают нагрузку на I-кеш и уменьшают нагрузку на предсказатель ветвления, чем условные ветки, (Кроме того, код ясен и легко читается.) Если вы используете x86-64, компилятор даже сохранит все в регистрах.
Обратите внимание, что вам будет сложно вставить этот код в программу, где ваш выбор имеет значение...
Мне нравится устранять условные прыжки как интеллектуальные упражнения. Имеет ли это какое-либо измеримое влияние на производительность, я понятия не имею:)
#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
, вероятно, намного быстрее.
Не уверен, является ли это наиболее эффективным или нет, но может быть, и это определенно короче:
int maximum = max( max(i, j), k);
Есть предложение включить это в библиотеку С++ под 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 ...); }
public int maximum(int a,int b,int c){
int max = a;
if(b>max)
max = b;
if(c>max)
max = c;
return max;
}
Я думаю, что "самым эффективным" вы говорите об эффективности, стараясь не тратить деньги на вычислительные ресурсы. Но вы можете ссылаться на написание меньшего количества строк кода или, возможно, на читаемость исходного кода. Ниже приведен пример, и вы можете оценить, находите ли вы что-то полезное или предпочитаете другую версию из полученных вами ответов.
/* 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);
}
}
#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;
}
int greater = a>b ? (a>c? a:c) :(b>c ? b:c);
System.out.println(greater);