Pregunta

A proyecto de clase implica clasificación de una matriz de cadenas, con cada cadena que contiene un número igual de columnas como esto:

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

El programa acepta un argumento de línea de comando para el que la columna para ordenar, y debe imprimir las cadenas ordenadas sin modificar.

Me gustaría utilizar strtok para romper copias de cada cadena en columnas, y hacer estructuras para cada línea como la siguiente:

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

Mi problema está en el puntero de función de comparación que qsort toma como un arg. Si he entendido bien, la función de comparación debe tomar dos punteros void const a los artículos que desee ordenar , y devolver un int. Esto significa que no puedo pasar punteros a estructuras en la función de comparación porque eso no es lo que se qsort clasificación. No puedo pasar en el número de columna para ordenar a la función de comparación, ya que sólo puede tomar dos argumentos. ¿Cómo puedo evitar esto para ordenar estas cadenas basado en columnas específicas?

editar Clasificación se limita a qsort o mi propia si realmente quiero. Dará la opción, elijo qsort. :)

editar # 2: El consenso parece ser el uso de una variable global para el número de columna, o simplemente utilizar qsort ordenar una matriz de estructuras. Yo no había pensado simplemente ordenar las estructuras, y utilizando el puntero en ellos para imprimir la cadena original. Creo que eso es lo que haré. Gracias por toda la ayuda!

¿Fue útil?

Solución

Puede pasar las estructuras de esta manera:

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);

Otros consejos

Suponiendo que usted no está limitado al uso de qsort, puede utilizar std :: sort, con un objeto funtor que almacena el número de columna. Si usted tiene que utilizar qsort, una solución rápida y sucia sería almacenar el número de columna en una variable global y el uso que en la función comparisson.

Las diferentes funciones de comparación, todos los cuales tienen toda la estructura, pero cada uno utiliza sólo una columna de comparacion.

C ++ o C? Con base en sus etiquetas, supongo que es C ++. Vamos a tratar de manera STL.

Debe utilizar std::sort en lugar de qsort. std::sort puede tener no sólo la función de puntero (en comparación con su alternativa C), pero cualquier objetos que se puede llamar como una función. Usted puede saber que las instancias de la clase pueden ser llamados como funciones con operator(). A continuación, la solución es sencilla: crear una clase "funtor" que va a crear diferentes funciones en la construcción. La llamada clase sería parecido a lo siguiente:

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

La clase funtor efectivamente crea un denominado "cierre": un objeto funcional creado de forma dinámica que tiene variables locales, pero no los comparte con otros objetos funcionales creados de esta manera. Se vería así:

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 */ };
};

Tenga en cuenta que en lugar de punteros comparación vacío "función" (es decir, la instancia de clase se crea) ha char * parámetros, por lo que no se moleste usted mismo con la conversión de tipos.

En C, por desgracia, no se puede hacer esto a la inversa de crear una variable global.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top