Pergunta

Um projecto classe envolve a triagem de uma matriz de cadeias, com cada cadeia contendo um número igual de colunas assim:

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

O programa aceita um argumento de linha de comando para o qual coluna para classificar, e deve imprimir as cordas ordenadas não modificado.

Eu gostaria de usar strtok para quebrar cópias de cada corda em colunas, e torná-estruturas para cada linha como esta:

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

Meu problema é no ponteiro de função de comparação que qsort toma como arg. Se bem entendi, a função de comparação deve levar dois ponteiros void const para os itens a serem classificados , e retornar um int. Isso significa que eu não pode passar ponteiros para estruturas para a função de comparação, porque não é isso que qsort será a classificação. Eu não posso passar o número da coluna para classificar para a função de comparação, porque ele só pode ter dois argumentos. Como posso obter em torno deste para classificar essas seqüências com base em colunas específicas?

Editar: A ordenação é limitado a qsort ou meu próprio se eu realmente quero. Dê a escolha, eu escolho qsort. :)

edição # 2: O consenso parece ser utilizar uma variável global para o número de coluna, ou apenas qsort uso para classificar uma matriz de estruturas. Eu não tinha pensado de apenas classificar as estruturas, e usando o ponteiro neles para imprimir a string original. Eu acho que é o que vou fazer. Obrigado pela ajuda todos!

Foi útil?

Solução

Você pode passar as estruturas como esta:

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

Outras dicas

Assumindo que você não está limitado a usar qsort, você pode usar std :: sort, com um objeto functor que armazena o número da coluna. Se você tem que usar qsort, uma solução rápida e suja seria armazenar o número da coluna em uma variável global e da utilização que na função comparisson.

diferentes funções de comparação, os quais levam toda a estrutura, mas cada um usa apenas uma coluna para comparation.

C ++ ou C? Baseado em suas tags, eu suponho que de C ++. Vamos maneira tentativa STL.

Você deve usar std::sort vez de qsort. std::sort pode levar não só ponteiro de função (em comparação com a sua alternativa C), mas qualquer objeto que pode ser chamado como função. Você pode saber que instâncias de classe pode ser chamado como funções com operator(). Em seguida, a solução é simples: criar uma classe "functor" que vai criar funções diferentes sobre a construção. A chamada tipo iria então ficar assim:

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

A classe functor efetivamente cria o chamado "fechamento": um objeto funcional criados dinamicamente que tem variáveis ??locais, mas não compartilhá-los com outros objetos funcionais criados desta forma. Ele ficaria assim:

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

Note que em vez de "função" de comparação ponteiros void (ou seja, a instância da classe que você cria) tem parâmetros char *, para que você não se preocupar-se com o tipo de fundição.

Em C, infelizmente, você não pode fazer isso a outra maneira de criar uma variável global.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top