Самый быстрый способ найти среднее значение тройного?

Cygwin предоставляет инструменты командной строки Unix в среде Windows.

42
задан Gnark 6 March 2014 в 09:26
поделиться

6 ответов

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

if (array[randomIndexA] > array[randomIndexB]) {
  if (array[randomIndexB] > array[randomIndexC]) {
    return "b is the middle value";
  } else if (array[randomIndexA] > array[randomIndexC]) {
    return "c is the middle value";
  } else {
    return "a is the middle value";
  }
} else {
  if (array[randomIndexA] > array[randomIndexC]) {
    return "a is the middle value";
  } else if (array[randomIndexB] > array[randomIndexC]) {
    return "c is the middle value";
  } else {
    return "b is the middle value";
  }
}

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

25
ответ дан 26 November 2019 в 23:12
поделиться

С тем же успехом вы могли бы написать это самым простым способом. Как вы сказали, есть только шесть возможностей. Ни один разумный подход не может быть быстрее или медленнее, поэтому просто выберите что-нибудь легкое для чтения.

Я бы использовал min () и max () для краткости, но я думаю, что три вложенных if / thens были бы не хуже.

3
ответ дан 26 November 2019 в 23:12
поделиться

Вот как вы можете выразить это, используя только условные выражения:

int a, b, c = ...
int middle = (a <= b) 
    ? ((b <= c) ? b : ((a < c) ? c : a)) 
    : ((a <= c) ? a : ((b < c) ? c : b));

РЕДАКТИРОВАНИЕ:

  1. Ошибки, указанные выше, обнаруженные @Pagas, были исправлены.
  2. @Pagas также указала, что вы не можете сделайте это с менее чем 5 условными выражениями, если вы используете только условные, но вы можете уменьшить это, используя временные переменные или замену значений.
  3. Я бы добавил, что трудно предсказать, будет ли чистое условное решение или решение присваивания быстрее. Скорее всего, это будет зависеть от того, насколько хорош JIT, но я думаю, что условную версию будет легче анализировать оптимизатору.
7
ответ дан 26 November 2019 в 23:12
поделиться

При использовании idxA в idxC в ary,

int ab = ary[idxA] < ary[idxB] ? idxA : idxB;
int bc = ary[idxB] < ary[idxC] ? idxB : idxC;
int ac = ary[idxA] < ary[idxC] ? idxA : idxC;

int idxMid = ab == bc ? ac : ab == ac ? bc : ab;

indexMiddle указывает на среднее значение.

Пояснение: из 3 минимумов 2 - это общий минимум, а другое значение должно быть средним. Поскольку мы проверяем равенство, мы можем сравнивать индексы в последней строке вместо того, чтобы сравнивать значения массива.

0
ответ дан 26 November 2019 в 23:12
поделиться

Если вам нужно найти одно из значений X, удовлетворяющее некоторым критериям, вы должны хотя бы сравнить это значение с каждым из остальных X-1. Для трех значений это означает как минимум два сравнения. Поскольку это «найти не самое маленькое и не самое большое значение», вы можете обойтись только двумя сравнениями.

Затем вам следует сосредоточиться на написании кода, чтобы вы могли очень четко видеть, что происходит, и сохранять его простым . Здесь это означает вложенные if. Это позволит JVM максимально оптимизировать это сравнение во время выполнения.

См. Решение, предоставленное Тимом ( Самый быстрый способ найти среднее значение тройки? ), чтобы увидеть пример этого . Строка с множеством кодов не обязательно оказывается большим кодом, чем вложенный знак вопроса с двоеточием.

2
ответ дан 26 November 2019 в 23:12
поделиться

или один лайнер для поиска индекса в массиве, содержащем среднее значение:

 int middleIndex = (a[0]<a[1]) ? ((a[0]<a[2) ? a[2] : a[0]) : ((a[1]<a[2) ? a[2] : a[1]);
-1
ответ дан 26 November 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: