I have an array:
int a[6] = {3, 4, 1, 2, 5, 6}
and I want to find the minimum and maximum element by using a pre-defined C function; is there one?
5 Answers
No, there isn't a minmax function in the standard library, but you could create one yourself.
Example:
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
// a struct to hold the min and max result
typedef struct {
int min;
int max;
} mm;
// a function to find the min and max values
mm minmax(const int *arr, size_t len) {
mm res = {INT_MAX, INT_MIN}; // start with min = INT_MAX, max = INT_MIN
for(const int *end = arr + len; arr != end; ++arr) {
if(*arr < res.min) res.min = *arr;
if(*arr > res.max) res.max = *arr;
}
return res;
}
int main() {
int a[6] = {3, 4, 1, 2, 5, 6};
mm res = minmax(a, sizeof a / sizeof *a);
printf("min: %d max: %d\n", res.min, res.max);
}
This could be generalized into a function that can find the min and max elements in any type of array, much like the qsort function can sort an array of any type of elements that are comparable in a strict weak ordering kind of way.
#include <stddef.h>
// a struct to hold pointers to the min and max elements
typedef struct {
const void *min;
const void *max;
} mm;
// The signature of a function for comparing elements.
// Such a function should return
// -1 if the left hand side is less than the right
// +1 if the right hand side is greater than the left
// 0 otherwise
typedef int (*comp_func)(const void *, const void *);
// the minmax function now takes these arguments:
// in_arr : a "const void*" to the array
// count : the number of elements
// size : the size of an element
// compare: a pointer to a function capable of comparing two elements
mm minmax(const void *const in_arr, size_t count, size_t size, comp_func compare) {
mm res = {0}; // both the min and max pointers are NULL
if(count) {
const char *cur = in_arr;
const char *const end = cur + count * size;
res.min = cur; // use the pointer to the first value as the pointer to min
res.max = cur; // ...and max
for(cur += size; cur != end; cur += size) {
// call the compare function
if(compare(cur, res.max) > 0) res.max = cur;
else if(compare(cur, res.min) < 0) res.min = cur;
}
}
return res;
}
With that minmax function in place, you could use it for an array of int or any type. You just have to supply a function to do the actual comparison of two elements.
Example:
#include <stdio.h>
int int_compare(const void *lhs, const void *rhs) {
return *((int*)lhs) < *((int*)rhs) ? -1 :
*((int*)lhs) > *((int*)rhs) ? 1 : 0;
}
int main() {
int a[6] = {3, 4, 1, 2, 5, 6};
mm res = minmax(a, sizeof a / sizeof *a, sizeof *a, int_compare);
// dereference the min and max pointers to get the values:
printf("min: %d max: %d\n", *((int*)res.min), *(int*)res.max);
}
2 Comments
else if. godbolt.org/z/s47PE4E3qelse that you added to your version made up for most of the diff. godbolt.org/z/osbxnzshK The else only works if we initialize the result with the value in the first array element - similar to what I'm doing in the more generic minmax function that I just added.No there is no standard C function. But You can do this yourself
int max = arr[0];
for (i = 1; i < n; i++)
if (arr[i] > max)
max = arr[i];
Whether it's big or small is obvious from the comparison inside the if. if >, is large. if <, is small
10 Comments
max to something like INT_MIN so any possible value for arr[i] is equal or larger.arr[0].arr[0] to maxC99 contains math.h
This has functions - fmin, fmax, fminl, fmaxl, fmaxf, fminf
#include <math.h>
double fmin( double x, double y );
float fminf( float x, float y );
long double fminl( long double x , long double y );
The fmin() functions return the value of the lesser argument.
#include <math.h>
double fmax( double x, double y );
float fmaxf( float x, float y );
long double fmaxl( long double x , long double y );
The fmax() functions return the value of the greater argument.
So, for the answer -
float max=0;
for (i = 0; i < n; i++)
max = fmaxf (max, arr[i]);
2 Comments
float max=0; causes the loop to fail for arrays that contain only negative values. Better initialize max to -INFINITY.As Ted Lyngmo says, there isn't, but you can create your own. Note however that if you wish to compute both the minimum and maximum at the same time, you can reduce the total number of comparisons to 3n/2 in the worst case, using the following trick to process 2 elements using 3 comparisons:
typedef struct {
int min;
int max;
} MinMax;
MinMax minmax(const int *arr, size_t len) {
MinMax res = {INT_MAX, INT_MIN};
while (len >= 2) {
int a = arr[0];
int b = arr[1];
if (a < b) {
if (a < res.min) res.min = a;
if (b > res.max) res.max = b;
} else {
if (b < res.min) res.min = b;
if (a > res.max) res.max = a;
}
arr += 2;
len -= 2;
}
if (len == 1) {
if (*arr < res.min) res.min = *arr;
if (*arr > res.max) res.max = *arr;
}
return res;
}
Comments
If you want constant time access to the minimum and maximum in an array, you can't have that. But depending on how the array is being populated, an array may be the wrong tool, or at least not the only tool to use. Binary heaps readily provide constant time access to the minimum or maximum (depending on whether it's a min heap or max heap) values.
So if you're reading input from the user, you can insert those values into a binary heap as you go and at any point the minimum or maximum value will be on top of the heap. You could even maintain two heaps and have both pieces of information simultaneously available. Maybe even insert into an array as well to maintain a record of insertion order.
Insertion has a higher cost, but read access has a much lower cost.
qsortfunction (which is predefined) and then print the first/last element of the array whichever is the largest depending on the comparator function you have provided or make a function of your own - but a predefined function to do all this is not available.