Another C exercise:
Write a function that takes an array of 'ints' as its input and finds the smallest and largest elements. It should also compute the median and mean. Use a
struct
holding the result as the return value
I found it quite awkward that there is no function to copy an array into another array, so I wrote one intdup
to use it in the median calculation.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
struct Result {
int smallest;
int largest;
double median;
double mean;
};
int cmp(void const *lhs, void const *rhs) {
const int *left = (const int *)lhs;
const int *right = (const int *)rhs;
return *left - *right;
}
int * intdup(const int * source, const size_t len)
{
assert(source);
int * p = malloc(len * sizeof(int));
if (p == NULL)
exit(1);
memcpy(p, source, len * sizeof(int));
return p;
}
int find_smallest(const int* array, const size_t len)
{
assert(array);
size_t i = 0;
int smallest = INT_MAX;
for (i = 0; i < len; ++i) {
if (array[i] < smallest)
smallest = array[i];
}
return smallest;
}
int find_largest(const int* array, const size_t len)
{
assert(array);
size_t i = 0;
int largest = INT_MIN;
for (i = 0; i < len; ++i) {
if (array[i] > largest)
largest = array[i];
}
return largest;
}
double calculate_median(const int* array, const size_t len)
{
assert(array);
int* calc_array = intdup(array, len);
int tmp = 0;
qsort(array, len, sizeof(int), cmp);
if (len % 2 == 0) { // is even
// return the arithmetic middle of the two middle values
return (array[(len - 1) / 2] + array[len / 2] ) /2.0;
}
else { // is odd
// return the middle
return array[len / 2];
}
}
double calculate_mean(const int* array, const size_t len)
{
assert(array);
double mean = 0;
size_t i = 0;
for (i = 0; i < len; ++i)
mean += array[i];
return mean / len;
}
struct Result calculate_values(const int* array, const size_t len)
{
assert(array);
struct Result result = { 0 };
result.smallest = find_smallest(array, len);
result.largest = find_largest(array, len);
result.median = calculate_median(array, len);
result.mean = calculate_mean(array, len);
return result;
}
void print_result(const struct Result* result)
{
assert(result);
printf("smallest: %i\n", result->smallest);
printf("largest: %i\n", result->largest);
printf("median: %f\n", result->median);
printf("mean: %f\n\n", result->mean);
}
int main()
{
int numbers[] = { 1,7,3,4,5,6,7,8,9 }; // 9 elements
// int numbers[] = { 1,7,3,4,5,6,7,8 }; // 8 elements
int len = sizeof(numbers) / sizeof(numbers[0]);
struct Result result = calculate_values(&numbers, len);
print_result(&result);
getchar();
return 0;
}
See the the revised code her: Calculate min, max, mean and median out of array Version 2
gsl_stats_int_mean()
(if the exercise allows it) \$\endgroup\$