| Алгоритм медианы трех чисел |
|
| Добавил(а) microsin |
int median3(int a, int b, int c) { Это алгоритм поиска медианы трех чисел (median of three). Он находит среднее по значению число среди трех целых чисел, не сортируя их полностью. Алгоритм особенно полезен, когда важна производительность и нужно часто находить медиану трех чисел. Медиана это значение, которое делит упорядоченный набор данных на две равные части: половина значений меньше или равна медиане, половина — больше или равна. [Формальное определение] Для набора чисел, упорядоченных по возрастанию: - Если количество чисел нечетное (n = 2k+1): - Если количество чисел четное (n = 2k): [Примеры] Нечетное количество: Набор: 3, 5, 1, 9, 2 Упорядочим: 1, 2, 3, 5, 9 Медиана = 3 (третий элемент) Четное количество: Набор: 4, 7, 1, 9, 3, 8 Упорядочим: 1, 3, 4, 7, 8, 9 Медиана = (4 + 7) / 2 = 5.5 [Свойства медианы] 1. Устойчивость к выбросам — в отличие от среднего арифметического, медиана мало чувствительна к экстремальным значениям. Набор: 1, 2, 3, 4, 100 Среднее = 22 Медиана = 3 (лучше представляет "типичное" значение) 2. Всегда существует — для любого набора данных. 3. Минимизирует сумму абсолютных отклонений: ∑|xᵢ - медиана| → min [Медианный фильтр в обработке сигналов] Функция median3 может использоваться для подавления импульсных помех: Вход: 10, 10, 20, 10, 10 Выход: 10, 10, 10, 10, 10 (выброс 20 отфильтрован) Это классическое применение — медианный фильтр отлично убирает "битые пиксели", импульсные шумы, выбросы данных, сохраняя при этом перепады сигнала (ступеньки). Функция median3 возвращает число, которое находится посередине при сортировке трех чисел по возрастанию. Например: - median3(5, 2, 8) вернет `5` Разберем логику: 1. Сначала сравниваем `a` и `b` 2. Если `a < b`, то: - Если `b < c`, то `b` — медиана 3. Если `a >= b`, то: - Если `a < c`, то `a` — медиана Пример простого использования: int main() { [Типичные сценарии применения] 1. В алгоритмах сортировки (например, для выбора опорного элемента в QuickSort): int pivot = median3(arr[left], arr[mid], arr[right]); 2. Обработка сигналов - для сглаживания значений (медианный фильтр). Он может сгладить короткий выброс сигнала, длительностью не более одной выборки: int smooth_value = median3(prev_value, current_value, next_value); Примечание: median3 относится к фильтрам с конечной импульсной характеристикой (FIR, или КИХ-фильтр). 3. Поиск среднего значения без переполнения: // Вместо (a + b + c)/3 (может переполнится): Преимущества median3: - Очень быстрый (без циклов, просто сравнение). Минусы: - Сложно читать из-за вложенных тернарных операторов. Более читаемая альтернатива: int median3(int a, int b, int c) { uint32_t. Алгоритм можно легко переделать на беззнаковые типы, при этом все сравнения будут работать корректно (нет риска неожиданного поведения с отрицательными числами). Более читаемая версия: #include < stdint.h> С использованием сортировки (максимально понятно): uint32_t median3(uint32_t a, uint32_t b, uint32_t c) { Вариант, оптимизированный для микроконтроллеров: uint32_t median3(uint32_t a, uint32_t b, uint32_t c) { Какой вариант выбрать? Вариант 1 — если нужна максимальная производительность и компактность (сохраняет логику оригинала). Все варианты корректно работают с полным диапазоном uint32_t от 0 до 4294967295. [Ссылки] 1. Image Filtering, Median Filtering site:cs.auckland.ac.nz. |