4

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?

nima
  • 7,796
  • 12
  • 36
  • 53

4 Answers4

4

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 *in_arr, size_t count, size_t size, comp_func compare) {
    mm res = {0}; // both the min and max pointers a NULL

    if(count) {
        // "cur" and "end" are here pointers to "const char[size]" elements,
        // so "++cur" will step "size" bytes in memory:
        const char (*cur)[size] = in_arr;
        const char (*end)[size] = cur + count;

        res.min = cur; // use the pointer to the first value as the pointer to min...
        res.max = cur; // ...and max

        for(++cur; cur != end; ++cur) {
            // call the compare function
            if(compare(cur, res.max) == 1) res.max = cur;
            else if(compare(cur, res.min) == -1) 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);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Or... we could keep it simple and _not_ use pointers, which at a glance seems to yield much faster code. Also `else if`. https://godbolt.org/z/s47PE4E3q – Lundin Sep 21 '21 at 07:45
  • @Lundin I think the `else` that you added to your version made up for most of the diff. https://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. – Ted Lyngmo Sep 21 '21 at 07:48
3

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

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Emin Niftiyev
  • 197
  • 1
  • 13
  • 1
    This wouldn't work with negative values. Better to set ```max``` to something like ```INT_MIN``` so any possible value for ```arr[i]``` is equal or larger. – sj95126 Sep 21 '21 at 05:59
  • 7
    Or just to the value of `arr[0]`. – Chris Sep 21 '21 at 06:00
  • 1
    Sure, that works too. :-) – sj95126 Sep 21 '21 at 06:01
  • 1
    @Chris @sj95126 i solved problem. i equalized `arr[0]` to `max` – Emin Niftiyev Sep 21 '21 at 06:05
  • 1
    @EminNiftiyev edited, in this case you don't need to evaluate `arr[0]` – David Ranieri Sep 21 '21 at 06:06
  • this is how i usually, but if I've to deal with 2d array, time complexity goes to O(n^2). isn't there a function, like there is for sort qsort – Shubham Wadkar Sep 21 '21 at 06:09
  • 1
    @ShubhamWadkar no, there is not, if you are under `gcc`/`clang` you can make use of `typeof` and `statement expressions` to build your own generic function-like macro: https://stackoverflow.com/questions/3437404/min-and-max-in-c – David Ranieri Sep 21 '21 at 06:11
  • 2
    @ShubhamWadkar How would it become O(n^2). You can see that there' s one plain for loop. It's O(n) always. There are no solutions better than O(n) for finding min/max elements. – Fractal Sep 21 '21 at 08:34
  • @Fractal if it is 2d array each loop for ever dimension wont that make n*n, please correct me if I am wrong. – Shubham Wadkar Sep 21 '21 at 11:20
  • @ShubhamWadkar No. That's not how you calculate the algorithm complexity. It's always calculated based on an abstract notion of size of the input. Regardless of the no. of elements/items that you want to process, the input size is always treated as `n`. It doesn't depend on whether you store them in 2D arrays, 3D arrays or n-D arrays – Fractal Sep 21 '21 at 12:13
1

C99 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]);
moi
  • 467
  • 4
  • 19
  • but the thing is for loop is still there, I was looking for something with constant time. But thanks, this was also something new for me. – Shubham Wadkar Sep 21 '21 at 07:06
1

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;
}
orlp
  • 112,504
  • 36
  • 218
  • 315