1

I wrote this function It should sort the strings in alphabetical order like father aunt >> aunt father. It should use only pointers.

void sort(char **arrPP[]){
int m=0;
for ( char ***p = arrPP; *p != NULL; ++p) {
    int z = 0;
    while (*(*p + z) != NULL) {
        m++;
        z++;
    }
}
for(int i=0;i<m;i++) {
    for (char ***p = arrPP; *p != NULL; ++p) {
        int u=0;
        while (*(*p + u) != NULL) {
            char **x = *p + u;
            int z = 1;
            for (char ***c = arrPP; *c != NULL; ++c) {

                while (*(*c + z) != NULL) {
                    if (strcmp(*x, *(*c + z)) > 0) {
                        char *o = *x;
                        *x = *(*c + z);
                        *(*c + z) = o;
                    }
                    z++;
                }
            }
            u++;
        }

    }
}

}

It should sort arrPP.

int main ()
{
char * arrP1 [ ] = { "father", "mother", NULL};
char * arrP2 [ ] = { "sister", "brother", "grandfather", NULL };
char * arrP3 [ ] = { "grandmother", NULL};
char *arrP4 [ ] = { "uncle", "aunt", NULL };
char ** arrPP [ ] = { arrP1, arrP2, arrP3, arrP4 , NULL};
printAllStrings(arrPP );// printALL Strings prints all strings and it works .
sort(arrPP);
printAllStrings(arrPP );
return 0;
}

the output should be:

father mother
sister brother grandfather
grandmother
uncle aunt
aunt brother
father grandfather grandmother
mother
sister
uncle

But the output is

    father mother
    sister brother grandfather
    grandmother
    uncle aunt
    //after sorting
    brother uncle
    mother sister grandmother
    father
    grandfather aunt

.What is wrong with the sort function ?How can I fix it or write something else than can help with my problem?

3
  • 1
    Hm, that's a very interesting sorting pattern. Anyway, your casts in strcmp((void*)x, (void*)c) hide errors: c is a char ***, x is a char **, but strcmp takes arguments of type (const) char *. That can't be right. Commented Jun 20, 2021 at 10:18
  • I changed it but the output is still wrong Commented Jun 20, 2021 at 11:20
  • 1
    There are other errors, for example z must be set to zero for each new sublist c. (It should probably be defined locally in the loop over c.) What you want to achieve is difficult. I suggest that you create an auxiliary linearized array of strings ["father", "mother", "sisret", ...], sort that and then re-assign the items of the sorted linearized list back to the original nested array. Commented Jun 20, 2021 at 11:34

1 Answer 1

1

You want to sort your array across two dimensions. Therefore, you must find a means to relate a linear index across all elements to a specific item in your nested list.

One way to do that is to create a linearized list of references to your items, then sort that list via the references. The extra level of indirection means that when you compare and swap two items in the linear list of references, you actually swap the items in the original nested list, too:

void sort1(char **arrPP[])
{
    char ***ref;
    int m = 0;
    
    // find length of linearized list

    for (char ***p = arrPP; *p != NULL; ++p) {
        int z = 0;
    
        while ((*p)[z++]) m++;
    }
    
    // assign references to original array

    ref = malloc(m * sizeof(*ref));
    m = 0;

    for (char ***p = arrPP; *p != NULL; ++p) {
        int z = 0;
    
        while ((*p)[z]) ref[m++] = *p + z++;
    }
    
    // sort linearized array.
    // This also sorts the original array via the references
    
    for (int i = 0; i < m; i++) {
        for (int j = i + 1; j < m; j++) {
            if (strcmp(*ref[i], *ref[j]) > 0) {
                char *swap = *ref[i];

                *ref[i] = *ref[j];
                *ref[j] = swap;
            }
        }
    }
    
    // clean up temporary array
    
    free(ref);
}

Another, perhaps a bit fancier way is to create an interator structure that allows you to iterate linearly over you nested lists:

struct iter {
    char ***p;
    unsigned i;
    char **value;
};

int next(struct iter *iter)
{
    if (iter->p == NULL) return 0;

    if (*iter->p && (*iter->p)[iter->i] == NULL) {
        iter->p++;
        iter->i = 0;
    }
    
    if (*iter->p == NULL) {
        iter->value = NULL;
        iter->i = 0;

        return 0;
    }

    iter->value = (*iter->p) + iter->i++;
    
    return 1;
}

Now you can traverse your nested lists like so:

struct iter iter = {arrPP};

while (next(&iter)) {
    puts(*iter.value);
}

This will print a flat, linearized list of your items. (But you could look at the p and i fields to decide whether you want to print a space or a new-line if you wanted to.)

Note how the value of the iterator is also a reference to the item, not the item itself. That means you can modify the items. With this iterator struct, your sorting algorithm is quite straightforward:

void sort(char **arrPP[])
{
    struct iter it = {arrPP};
    
    while (next(&it)) {
        struct iter other = it;
        
        while (next(&other)) {
            if (strcmp(*it.value, *other.value) > 0) {
                char *swap = *it.value;

                *it.value = *other.value;
                *other.value = swap;
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.