В этом руководстве мы рассмотрим, как использовать переменные аргументы в C для реализации процентильных функций. Процентиль — это статистический термин, который относится к показателю, ниже которого падает определенный процент данных. Например, 90-й процентиль набора данных — это значение, ниже которого находится 90 % данных.
Прежде чем мы углубимся в реализацию процентильных функций в C, давайте сначала разберемся с концепцией переменных аргументов.
Переменные аргументы в C
Переменные аргументы в C позволяют функции принимать различное количество аргументов. Эти типы функций полезны в случаях, когда мы не знаем точное количество аргументов, которые будут переданы функции во время компиляции. Функция переменных аргументов в C реализована с использованием заголовочного файла stdarg.h
.
Заголовочный файл stdarg.h
содержит макросы и функции для обработки переменных аргументов. Макросы: va_start
, va_arg
и va_end
. va_start
macro инициализирует указатель аргумента, va_arg
macro извлекает следующий аргумент, а va_end
macro освобождает все ресурсы, используемые указателем аргумента.
Теперь, когда у нас есть общее представление о переменных аргументах, давайте перейдем к реализации процентильных функций в C.
Реализация процентильных функций в C
Для целей этого руководства мы будем реализовывать две функции процентиля — одну для вычисления n-го процентиля, а другую — для вычисления медианы.
Функция n-го процентиля
Функция n-го процентиля принимает два аргумента — значение процентиля и переменное количество точек данных. Функция возвращает значение n-го процентиля.
#include <stdarg.h> double nth_percentile(int n, int count, ...) { int i, j; double temp, percentile; double* array = malloc(count * sizeof(double)); va_list args; va_start(args, count); for (i = 0; i < count; i++) { array[i] = va_arg(args, double); } va_end(args); for (i = 0; i < count; i++) { for (j = i + 1; j < count; j++) { if (array[j] < array[i]) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } percentile = ((double)n / 100) * (count - 1) + 1; if (percentile == (int)percentile) { return array[(int)percentile - 1]; } else { int k = (int)percentile; double d = percentile - k; return array[k - 1] + d * (array[k] - array[k - 1]); } }
Пройдемся по реализации шаг за шагом.
- Начнем с объявления функции 1, которая принимает два аргумента — n и count — и многоточие (три точки), указывающее, что функция принимает переменное количество аргументов.
- Затем мы объявляем переменные i, j, temp, процентиль и массив. Переменная массива представляет собой динамически выделяемый массив двойников для хранения точек данных.
- Затем мы используем тип данных va_list для объявления указателя аргумента, args.
- Макрос va_start используется для инициализации указателя аргумента args с помощью аргумента count.
- Затем мы используем цикл for для перебора переменных аргументов и сохранения их в массиве.
- Макрос va_end используется для освобождения любых ресурсов, используемых указателем аргумента, args.
- Затем мы используем вложенный цикл for для сортировки точек данных в порядке возрастания.
- Мы вычисляем значение процентиля, используя следующую формулу: ((double)n / 100) * (count — 1) + 1. Эта формула основана на определении процентиля.
- Мы проверяем, является ли значение процентиля целым числом. Если это так, мы возвращаем точку данных по этому индексу в отсортированном массиве. Если это не так, мы интерполируем между двумя точками данных, чтобы получить значение процентиля.
- Наконец, мы освобождаем память, выделенную для переменной массива, и возвращаем значение процентиля.
Медианная функция
Медианная функция принимает переменное количество точек данных в качестве аргументов и возвращает медианное значение. Медиана — это значение, которое отделяет нижнюю половину набора данных от верхней половины.
double median(int count, ...) { double* array = malloc(count * sizeof(double)); int i, j; double temp, median; va_list args; va_start(args, count); for (i = 0; i < count; i++) { array[i] = va_arg(args, double); } va_end(args); for (i = 0; i < count; i++) { for (j = i + 1; j < count; j++) { if (array[j] < array[i]) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } if (count % 2 == 0) { median = (array[count / 2 - 1] + array[count / 2]) / 2; } else { median = array[count / 2]; } free(array); return median; }
Реализация функции медианы аналогична реализации функции n-го процентиля, с той лишь разницей, что мы не принимаем значение процентиля в качестве аргумента.
- Начнем с объявления функции median, которая принимает один аргумент — count — и многоточие (три точки), указывающее, что функция принимает переменное количество аргументов.
- Затем мы объявляем переменные i, j, temp, медиана и массив. Переменная массива представляет собой динамически выделяемый массив двойников для хранения точек данных.
- Затем мы используем тип данных va_list для объявления указателя аргумента, args.
- Макрос va_start используется для инициализации указателя аргумента args с помощью аргумента count.
- Затем мы используем цикл for для перебора переменных аргументов и сохранения их в массиве.
- Макрос va_end используется для освобождения любых ресурсов, используемых указателем аргумента, args.
- Затем мы используем вложенный цикл for для сортировки точек данных в порядке возрастания.
- Мы проверяем, является ли количество точек данных четным или нечетным. Если оно четное, мы берем среднее значение двух средних значений в качестве медианы. Если это нечетно, мы принимаем среднее значение как медиану.
- Наконец, мы освобождаем память, выделенную для переменной массива, и возвращаем медианное значение.
Заключение
В этом руководстве мы рассмотрели, как использовать переменные аргументы в C для реализации процентильных функций. Мы реализовали две функции — функцию n-го процентиля и функцию медианы — используя заголовочный файл stdarg.h.
Переменные аргументы — мощная функция языка C, которая позволяет нам писать более гибкие и универсальные функции. Немного попрактиковавшись, вы сможете начать включать переменные аргументы в свои собственные программы на C.