Domanda

Un progetto di classe coinvolge ordinare un array di stringhe, con ogni stringa contenente un numero uguale di colonne così:

Cartwright   Wendy    93
Williamson   Mark     81
Thompson     Mark     100
Anderson     John     76
Turner       Dennis   56

Il programma accetta un argomento della riga di comando per il quale colonna per ordinare, e dovrebbe stampare le stringhe ordinate non modificato.

Vorrei utilizzare strtok per spezzare copie di ogni stringa in colonne, e rendere le strutture per ogni linea in questo modo:

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}

Il mio problema è nel puntatore a funzione di confronto che qsort prende come un ARG. Se ho capito bene, la funzione di confronto deve prendere due puntatori void const alle voci da ordinare , e restituire un int. Ciò significa che non posso passare puntatori per le strutture in funzione di confronto, perché non è quello che qsort saranno ordinamento. Non posso passare il numero di colonna per ordinare al funzione di confronto, perché può avvenire solo due args. Come posso ottenere intorno a questo per ordinare queste stringhe in base a specifiche colonne?

modifica L'ordinamento è limitato a qsort o il mio, se voglio davvero. Dare la scelta, scelgo qsort. :)

Modifica # 2: Il consenso sembra essere o utilizzare una variabile globale per il numero di colonna, o semplicemente usare qsort per ordinare un array di strutture. Non avevo pensato di appena l'ordinamento le struct, e utilizzando il puntatore a loro di stampare la stringa originale. Credo che questo sia quello che farò. Grazie per l'aiuto tutti!

È stato utile?

Soluzione

È possibile passare le struct in questo modo:

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}
...

line*  Lines[max_lines]; // here you store the structs

int
cmp_lines( const void *elem1, const void *elem2 )
{
    line*  line1 = *(line**)elem1;
    line*  line2 = *(line**)elem2;
    // do the comparisons
}

qsort(Lines, max_lines, sizeof(line*), cmp_lines);

Altri suggerimenti

Supponendo che non si è limitati ad usare qsort, è possibile utilizzare std :: sort, con un oggetto funtore che memorizza il numero di colonna. Se si deve usare qsort, una soluzione rapida e sporca potrebbe essere quella di memorizzare il numero di colonna in una variabile globale e l'uso che nella funzione comparisson.

funzioni comparatori differenti, ognuno dei quali prendono tutta struct, ma ognuno usa solo una colonna per comparazione.

C ++ o C? Sulla base delle vostre etichette, presumo che sia C ++. Proviamo modo STL.

Si dovrebbe usare std::sort invece di qsort. std::sort può avvenire non solo puntatore alla funzione (rispetto alla sua alternativa C), ma qualsiasi oggetto che può essere chiamato come una funzione. Si può sapere che le istanze di classe possono essere chiamati come funzioni con operator(). Allora la soluzione è semplice: creare una classe "funtore" che creerà funzioni differenti su di costruzione. La chiamata sorta sarebbe quindi simile che:

std::sort(array, array+size, comparator(2 /* sort by column #2 */));

La classe funtore crea effettivamente una cosiddetta "chiusura": un oggetto funzionale creato in modo dinamico che ha variabili locali, ma non li condivide con altri oggetti funzionali creati in questo modo. Si sarebbe simile a questa:

class comparator{
  private: unsigned int field_n;
  public: comparator(unsigned int _field_n) : field_n(_field_n) {};
  public: int operator () (char const *  lhs, char const * rhs)
       { /* compare here fields with index field_n */ };
};

Si noti che, invece di vuoto confronto puntatori "funzione" (vale a dire l'istanza della classe si crea) ha char * parametri, quindi non ci si preoccupano con il tipo di getto.

In C, purtroppo, non è possibile fare questo il contrario rispetto alla creazione di una variabile globale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top