
В этом руководстве мы рассмотрим, как использовать переменные аргументы в 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.