简体   繁体   English

按结构中的属性值对结构进行排序

[英]Sort Structs by the value of an attribute in it

i am trying to sort a struct by the value of a double attrib in it, kind of like this我正在尝试根据结构中的双属性值对结构进行排序,有点像这样

#include <stdio.h>
#include <stdlib.h>

double arr[] = {1.023, 1.22, 1.56, 2, 5, 3.331};

int cmp(const void *x, const void *y)
{
  double xx = *(double*)x, yy = *(double*)y;
  if (xx < yy) return -1;
  if (xx > yy) return  1;
  return 0;
}

int main() {
    qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), cmp);
}

My issue is when i try to sort a list of struct named ann as shown below我的问题是当我尝试对名为 ann 的结构列表进行排序时,如下所示

typedef struct ann {
    int inputs;                 /* Number of input neurones      */
    int hidden_layers;          /* Number of hidden layers       */
    int hidden;                 /* Number of hidden neurones     */
    int outputs;                /* Number of output neurons.     */
    int weights;                /* Total nof weigths(chromosomes)*/
    int neurons;                /* Total Number of neurones      */
    double *weight;             /* The weights(genotype)         */
    double *output;             /* Output                        */
    double fitness;              /* Total fitness of the network    */
    double *delta;
    actfun activation_hidden;   /* Hidden layer activation func  */
    actfun activation_output;   /* Output layer activation func  */
} ann;

qsort does not alter the order qsort 不会改变顺序

here is my actual code这是我的实际代码

ann **population = malloc ( population_size * sizeof(ann*));

    for( i = 0; i < population_size; i++ ){
        population[i] = create( trainset->num_inputs, 1 , hidden, trainset->num_outputs);
    }

qsort( population, population_size, sizeof(ann), compareAnn);

int compareAnn(const void* a, const void* b)
{
  const ann* pa = (const ann*)a;
  const ann* pb = (const ann*)b;
  return pa->fitness - pb->fitness;
}

Also here is the create() function这里还有 create() 函数

ann *create   ( int inputs, int hidden_layers, int hidden, int outputs ) {

    const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0;
    const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs;
    const int total_weights = (hidden_weights + output_weights);

    const int total_neurons = (inputs + hidden * hidden_layers + outputs);

    /* Allocate extra size for weights, outputs, and deltas. */
    const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
    ann *ret = malloc(size);
    if (!ret) return 0;

    ret->inputs = inputs;
    ret->hidden_layers = hidden_layers;
    ret->hidden = hidden;
    ret->outputs = outputs;

    ret->weights = total_weights;
    ret->neurons = total_neurons;

    /* Set pointers. */
    ret->weight = (double*)((char*)ret + sizeof(ann));
    ret->output = ret->weight + ret->weights;
    ret->delta = ret->output + ret->neurons;

    return ret;
}

I understand this may be trivial, but i have tried to do this in so many ways and i cant seem to figure it out, and i have spend many many hours trying to fix it already, and any help will be great, thanks to all in advance.我知道这可能是微不足道的,但我已经尝试以多种方式来做到这一点,但我似乎无法弄清楚,而且我已经花了很多时间试图修复它,任何帮助都会很棒,谢谢大家提前。

The variable population has the type ann ** .变量population具有类型ann ** Each element of the allocated array has the type ann * .So the function qsort should be called like分配数组的每个元素都具有类型ann * 。所以函数qsort应该像这样调用

qsort( population, population_size, sizeof( ann * ), compareAnn );

Within the comparison function you should write在比较函数中,你应该写

int compareAnn(const void* a, const void* b)
{
  const ann* pa = *( const ann ** )a;
  const ann* pb = *( const ann ** )b;
  return ( pb->fitness < pa->fitness ) - ( pa->fitness - pb->fitness );
}

Pay attention to the return statement.注意return语句。 Otherwise the difference of doubles in the return statement converted to the type int can produce an unexpected result.否则,转换为int类型的 return 语句中的双精度差异会产生意外结果。

return pa->fitness - pb->fitness;

Also this memory allocation还有这个内存分配

const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
ann *ret = malloc(size);

does not make sense.没有意义。 Either allocate a memory of the size equal to sizeof( ann ) or use another structure that encloses the structure ann.要么分配大小等于sizeof( ann )的内存,要么使用另一个包含结构体 ann 的结构体。

Here is a demonstrative program.这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>

struct A
{
    double x;
};

int cmp( const void *a, const void *b )
{
    const struct A *left  = *( const struct A ** )a;
    const struct A *right = *( const struct A ** )b;

    return ( right->x < left->x ) - (  left->x < right->x );
}

int main(void) 
{
    size_t n = 10;
    struct A **a = malloc( n * sizeof( struct A * ) );

    for ( size_t i = 0; i < n; i++ )
    {
        a[i] = malloc( sizeof( struct A ) );
        a[i]->x = ( double )( n - i ) / n;
    }

    for ( size_t i = 0; i < n; i++ ) printf( "%.1f ", a[i]->x );
    putchar( '\n' );

    qsort( a, n, sizeof( struct A * ), cmp );

    for ( size_t i = 0; i < n; i++ ) printf( "%.1f ", a[i]->x );
    putchar( '\n' );

    for ( size_t i = 0; i < n; i++ ) free( a[i] );
    free( a );

    return 0;
}

Its output is它的输出是

1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM