Thread: Better way to do this?

  1. #1
    Registered User
    Join Date
    Sep 2020
    Posts
    45

    Better way to do this?

    I wonder if there is a better way of doing this. I don't lik the repetetive code in sorted_asc and sorted_desc.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdbool.h>
    
    
    bool sorted_asc(void *data, size_t size, size_t datasize, 
                    int (*compare)(const void *a, const void* b))
    {
        unsigned char *p = data;
        for (int i = 0; i < size - 1 ; i++)
        {
            if(compare(p + i * datasize, p + ((i + 1) * datasize)) > 0)
                return false; 
        }
        return true;
    }
    
    
    bool sorted_desc(void *data, size_t size, size_t datasize, 
                    int (*compare)(const void *a, const void* b))
    {
        unsigned char *p = data;
        for (int i = 0; i < size - 1 ; i++)
        {
            if(compare(p + i * datasize, p + ((i + 1) * datasize)) < 0)
                return false; 
        }
        return true;
    }
    
    /* sorted - check if an array is sorted - either in descending or  
     * ascending order
     *
     * Possible use:
     * assert(sorted(...));
     * qsort(...)
     * or
     * assert(!sorted(...))
     * qsort(...)
     */
    bool sorted(void *data, size_t size, size_t datasize, 
                       int (*compare)(const void *a, const void* b))
    {
        return sorted_asc(data, size, datasize, compare) ||
                  sorted_desc(data, size, datasize, compare);
        
    }
    
    
    int compare_int(const void *a, const void *b)
    {
        const int *i1 = a;
        const int *i2 = b;
        
        return *i1 - *i2;
    }
    
    
    int main(int argc, char **argv)
    {
        int a1[] = {1,2,3,4,5};
        int a2[] = {5,4,3,2,1};
        int a3[] = {3,2,1,4,5};
        
        assert(sorted_asc(a1, 5, sizeof(int), compare_int));
        assert(sorted_desc(a2, 5, sizeof(int), compare_int));
        assert(!sorted(a3, 5, sizeof(int), compare_int));
        assert(sorted(a1, 5, sizeof(int), compare_int));
        assert(sorted(a2, 5, sizeof(int), compare_int));
        
        printf("ALL TESTS PASSED\n");
        return EXIT_SUCCESS;
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,047
    It's hard for me to imagine a use case where I cared that an array was sorted but didn't care whether it was ascending or descending. Probably not worth a dedicated function.

    You could define separate compare_int_asc and compare_int_desc functions and pass the desired one.

    Consider a typedef:
    Code:
    typedef int (*Compare)(const void *a, const void* b);
    void *data should be const void *data.
    i should be size_t.
    Don't define argc and argv if you aren't using them.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <assert.h>
     
    typedef int (*Compare)(const void *a, const void* b);
     
    bool sorted(const void *data, size_t size, size_t datasize, Compare compare) {
        const unsigned char *p = data;
        for (size_t i = 0; i < size - 1; i++)
            if (compare(p + i * datasize, p + (i + 1) * datasize) > 0)
                return false; 
        return true;
    }
     
    int compare_int_asc(const void *a, const void *b) {
        const int *ia = a, *ib = b;
        return *ia - *ib;
    }
     
    int compare_int_desc(const void *a, const void *b) {
        const int *ia = a, *ib = b;
        return *ib - *ia;
    }
     
    int main() {
        int a1[] = {1,2,3,4,5};
        int a2[] = {5,4,3,2,1};
        int a3[] = {3,2,1,4,5};
     
        assert(sorted(a1, 5, sizeof(int), compare_int_asc));
        assert(sorted(a2, 5, sizeof(int), compare_int_desc));
        assert(!(sorted(a3, 5, sizeof(int), compare_int_asc)
              || sorted(a3, 5, sizeof(int), compare_int_desc)));
     
        printf("ALL TESTS PASSED\n");
        return 0;
    }
    Last edited by john.c; 09-22-2020 at 07:43 AM.
    Philosophy is a battle against the bewitchment of our intelligence by means of language. - Wittgenstein

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    45
    Thank you John. I like your solution much better.

Popular pages Recent additions subscribe to a feed

Tags for this Thread