qsort : Ursprünglichen Index merken?
-
Ja, hm, das muss ich mir nochmal in Ruhe überlegen mit den structs
Vielleicht kannst du ja das warning anschauen bzw. mir meinen Fehler sagen?
-
julieann schrieb:
... double aa = *a; double bb = *b; if (aa > bb) return -1; else if (bb < aa) return 1; else return 0; ...
hatten wir das nicht mal so, wegen overflows oder so
lg lolo
-
Heut abend,wenn ich wieder am rechner bin,probier ich das mal.obwohl ic mir nich vorstellen kann,dass das mein problem vom qsort Aufruf sein soll.
-
Versuchs mal so:
#include <stdio.h> #include <stdlib.h> #define ELEMENTS(array) (sizeof(array) / sizeof(*array)) typedef struct { int index; double wert; } numeriert; int compare(const void *a, const void *b) { return ((numeriert *)a)->wert > ((numeriert *)b)->wert; } int main(void) { numeriert array[] = {{0, 3.14}, {1, 42.0}, {2, 2.72}}; qsort(array, ELEMENTS(array), sizeof(numeriert), compare); for (size_t i = 0; i < ELEMENTS(array); i++) printf("%i-ter wert: %lf, war vorher an Stelle %d\n", i, array[i].wert, array[i].index); }
Oder so ähnlich.
-
Also, irgendwie komme ich mit der Syntax nicht ganz zurecht
Ich schreibe mal einen Auszug aus meinem Code:
Zunächst definiere ich die structs, ist das richtig so? Ich will also in jedem RSPinstance ein struct EFF haben.
typedef struct { int index; double *efficiency; } EFF; typedef struct { int C; /* Capacity */ int *w; /* weight */ int *p; /* profit */ int n; /* number of elements */ char *x; /* solution, 0 = dont pack, 1 = pack, 2 = dont know yet */ EFF *effundindex; } RSPinstance;
Nun will ich in eine Funktion eine Instanz übergeben und dort zunächst das Array efficiency belegen. Dieses ist ja Element eines structs EFF (genannt effundindex im struct RSPI). Zunächst einfach mal mit 1 in jedem Eintrag, der Rest kann ja folgen. Muss ich nun noch Speicher für effunindex alloziieren? (für RSPI passiert das natürlich im Programm)? Wenn ja wie? Und wie ist nun die korrekte Syntax um auf die Elemente von efficiency zuzugreifen? Ich weiß irgendwie nicht weiter.
void Greedy(RSPinstance *RSPI) { int j; for (j=0; j < RSPI->n, j++) { *(RSPI->effundindex).efficiency[j]=1; printf("%lf",*(RSPI->effundindex).efficiency[j]); } }
-
julieann schrieb:
printf("%lf",RSPI.effundindex[j].efficiency);
evtl. eher so und das efficiency ist dann kein zeiger sondern ein "double efficiency;"
lg lolo
-
Das funktioniert so noch nicht.
Aber muss es denn nicht so sein (gedanklich): RSPI vom Typ struct RSPinstance enthält u.a. effundindex, ein struct vom Typ EFF. Dieses enthält das Array efficiency, sowie einen int Wert index. Im Array efficiency speichere ich die Quotienten aus den p[j] und w[j], den Vektoren, die in RSPI enthalten sind als member ? Verständlich?
-
OK, ich hab's jetzt...poste später nochmal den Code
-
RSPI->effundindex = (EFF*) malloc(sizeof(EFF) * RSPI->n); for (j=0; j < RSPI->n; j++) { (RSPI->effundindex[j]).efficiency= ((double)RSPI->p[j])/((double)RSPI->w[j]); /*printf("%lf %d %d\n",(RSPI->effundindex[j]).efficiency, RSPI->p[j], RSPI->w[j]); */ }
So klappt es.
Jetzt habe ich aber ein neues Problem:
Ich muss für qsort ja eine compare Funktion schreiben. Diese muss also das Array effundindex sortieren nach dem Wert efficiency. Könnt ihr mjir bei der compare Funktion helfen?
Meine stimmt so wohl noch nichtint compare(const void *a, const void *b) { EFF *ia = (EFF *)a; EFF *ib = (EFF *)b; return (int)(*ia->efficiency - *ib->efficiency); }
-
Könnte das stimmen: ? I
int compare(const void *a, const void *b) { EFF * const *one = a; EFF * const *two = b; return ((*one)->efficiency - (*two)->efficiency); }
Ich bin nicht sicher, weil ich den Aufruf der qsort Funktion damit noch nicht ganz raus habe...
qsort(RSPI->effundindex, RSPI->n, sizeof(EFF), compare);
So bekomme ich einen Speciherzugriffsfehler... weiß jemand Rat?
-
Ein simples Minus geht mit doubles nicht, weil die Differenz zB -0.3 sein kann, das wird dann auf 0 abgeschnitten, wenn ein int draus gemacht wird; und bedeutet dann Gleichheit für qsort(). Dann werden Zahlen falsch sortiert, die sich um weniger als 1.0 voneinander unterscheiden. Eine ordentliche Vergleichsfunktion könnte so aussehen:
int compare(void const *a, void const *b) { double aa = ((EFF *)a)->efficiency; double bb = ((EFF *)b)->efficiency; if (aa > bb) return 1; else if (bb > aa) // hier war noobLolos Tippfehler return -1; else return 0; }
Vorausgesetzt, dass EFF ein Typname für eine Struktur ist, die zB so festgelegt ist:
typedef struct { ... double efficiency; ... } EFF;
-
julieann schrieb:
Ich bin nicht sicher, weil ich den Aufruf der qsort Funktion damit noch nicht ganz raus habe...
Das geht so:
typedef struct { int wasauchimmer; double efficiency; } EFF; /* ein Array davon: */ EFF array [] = {{0, 0.0}, {1, 1.0}, ...}; /* dann so aufrufen: */ qsort(array, sizeof(array) / sizeof(*array), sizeof(*array), compare); /* ^ Zeiger auf den Bereich ^ Anzahl der Elemente im Bereich ^ Grösse eines Elementes ^ Vergleichsfunktion */
-
Komme gerade nicht an meinen Quellcode, bin bei der Arbeit.
Also, ja, genauso ist EFF natürlich angelegt.Grundsätzlich weiß ich ja, wie ich qsort aufrufe.
Stand da irgendwie auf dem Schlauch,werde das nachher nochmal so testen. Danke schonmal!!