[C] quicksort probleem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 20-09 14:54

Mr_gadget

C8H10N4O2 powered

Topicstarter
Het is waarschijnlijk relatief eenvoudig maar ik kom er helaas zelf niet uit.
Ik wil de 2D array names sorteren. Met de string test lukt dat prima. Maar met de pointer naar de array lukt het niet. Deze worden wel gesorteerd maar niet in zinnige volgorde. Zou ik hiervoor een eigen compare functie moeten maken ofzo?

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double sort_names(char **names, int name_count)
{
    int i=0;
    char *pos=NULL;
    char test[][20] = {"MARY", "PATRICIA", "LINDA", "PAMALA", "BARBARA"};
    printf("start sorting");
    //printf("names: %s \n", ((names)[1])); 
    
     for (i = 0; i < 4; ++i){
         printf("names before sort: %s \n", ((names)[i])); 
     }

     qsort(names, name_count, sizeof(names[1]), (int(*)(const void*, const void*))strcmp);
     qsort(test, 4, sizeof(test[1]), (int(*)(const void*, const void*))strcmp);
     for (i = 0; i < 4; ++i){
    printf("%s\n", test[i]);
    }
     for (i = 0; i < 5; ++i){
         printf("names after sort: %s \n", ((names)[i])); 
     }


}

Acties:
  • 0 Henk 'm!

Verwijderd

Je functie is raar. Geen return type. Verder beetje een rommel. Maar zoiets:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int compare (const void* a, const void* b)
{
  return strcmp(*(const char**) a, *(const char**) b);
}

int main()
{
    int i;
    char* test[] = { "Aap", "Noot", "Mies", "Kat", "Pot" };
    qsort(test, 5, sizeof(char*), compare);

    for (i = 0; i < 5; ++i)
    {
        printf("%s", test[i]);
    }

    return 0;
}


Dus: comparator krijgt binnen: pointer naar string (in de vorm van pointer naar const char pointer). Dit in de vorm van een const void pointer. Even recasten, dereferencen en door strcmp gooien. Verder: size van elementen die vergeleken worden: qsort dengt dat hij pointers naar de daadwerkelijke strings aan het comparen is (want: dat zit in de array test). Denk dat je er zo wel uitkomt?

[ Voor 30% gewijzigd door Verwijderd op 09-02-2011 13:55 ]


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Je code is niet echt het toppunt van schoonheid, al die printfs maken het ook niet duidelijker (en die hardcoded limieten op je loops die verschillend zijn overal helpen ook niet).

Het zou helpen als je vertelt WAAR exact het fout gaat (regelnummer, gebruik een debugger). Al die printfs, doen die het wel goed? Op welke regel crasht het? Met welke code (access violation? SIG_SEGV?)? Of is het een compile error?

Of geef eens een (gedeelte van) de input van de functie voor een case waar het niet werkt. Hier kan ik weinig mee.

Ook:
Sorts the num elements of the array pointed by base, each element size bytes long, using the comparator function to determine the order.
The sorting algorithm used by this function compares pairs of values by calling the specified comparator function with two pointers to elements of the array
Let op de bold :), je compare functie krijgt const char **, niet const char *
En dat had Hel Gast hierboven natuurlijk al gefixt :)

[ Voor 41% gewijzigd door MLM op 08-02-2011 13:30 ]

-niks-


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Euh, nee. De compare functie krijgt een pointer naar een const char (*)[20]. Hel Gast's code werkt omdat hij zelf een const char *[] (een array van pointers) gebruikt om z'n data in op te slaan, en geen const char[][20] (een array van char-arrays) zoals Mr_gadget doet.

't Mooie daarvan is dat het gewoon binary compatible is met strcmp(). Een const char (*)[20] is een pointer naar een array van 20 chars. Aangezien de pointer naar het begin wijst, kun je die dus casten naar een char*. Dit werkt dus zoals verwacht:

C++:
1
2
3
4
5
6
7
8
int main()
{
    char names[][20] = { "karel", "hendrik", "anton", "pieter", "bernard" };
    qsort(names, 5, 20, (int(*)(const void*,const void*))strcmp);

    for (int i = 0; i < 5; i++)
        std::cout << names[i] << std::endl;
}


.edit: oh wacht, ik lees verkeerd. Met die strings ging het ook goed, het ging juist om de names array wat idd een const char ** is 8)7. Dan zul je inderdaad Hel Gast's methode moeten gebruiken.

[ Voor 123% gewijzigd door .oisyn op 08-02-2011 14:02 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

.oisyn schreef op dinsdag 08 februari 2011 @ 13:47:
Euh, nee. De compare functie krijgt een const char (*)\[20]. Helgast's code werkt omdat hij zelf een const char *[] (een array van pointers) gebruikt om z'n data in op te slaan, en geen const char[]\[20] (een array van char-arrays) zoals Mr_gadget doet.
Zoals ik de TS begrijp wilt hij dat ook, gezien zijn functie argument "char **", en zijn eerste qsort waar hij dat in stopt, en dan krijgt strcmp effectief een char ** voor zijn kiezen die hij (foutief) wegcast naar void *

Edit: ik zag je edit te laat

[ Voor 11% gewijzigd door MLM op 08-02-2011 14:01 ]

-niks-


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zie mijn edit ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1