使用 qsort 对结构数组进行排序
Sorting an array of structs with qsort
我正在编写一个对“二元数组”进行排序的程序。基本上,我有一个包含 BigramObjects 的数组。每个对象都包含一个“count”和“bigram”。我想按“计数”的顺序对我的二元数组进行排序。下面是我试图用来解决这个问题的代码。
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "bigramArray.h"
typedef struct bigramObject *BigramObject;
struct bigramObject {
char *bigram;
int count;
};
struct bigramArray {
BigramObject *data;
int size;
};
#define NUMBER_OF_CHARACTERS (256)
BigramArray bigramArrayCreate(void) {
BigramArray b = malloc(sizeof(struct bigramArray));
assert(b);
b->size = NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS;
b->data = malloc(sizeof(struct bigramObject) * NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS);
assert(b->data);
for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
BigramObject obj = malloc(sizeof(struct bigramObject));
assert(obj);
//Store the bigram for this cell
obj->bigram = malloc(sizeof(char) * 2);
assert(obj->bigram);
obj->bigram[0] = i;
obj->bigram[1] = j;
obj->count = 0;
b->data[i * NUMBER_OF_CHARACTERS + j] = obj;
}
}
return b;
}
void bigramArrayDestroy(BigramArray b) {
for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
free(b->data[i * NUMBER_OF_CHARACTERS + j]->bigram);
free(b->data[i * NUMBER_OF_CHARACTERS + j]);
}
}
free(b->data);
free(b);
}
int compare(const void *a, const void *b) {
const BigramObject objA = (BigramObject) a;
const BigramObject objB = (BigramObject) b;
return objA->count - objB->count;
}
void sortBigramArray(BigramArray b) {
// UP TO HERE IS GOOD
qsort(b->data, b->size, sizeof(BigramObject), compare);
}
但是,当我测试排序时,程序根本不对任何内容进行排序。我有 运行 gdb 在一个完全普通的二元数组上(基本上所有的计数都是 0),我注意到 objA 和 objB 的计数都不是 0(它们更接近像 4215872 这样的数字并且有差异在我逐步完成一些之后是二的倍数)。在 sortBigramArray 函数中,所有计数仍然为 0。有人可以向我解释为什么会发生这种变化吗?
compare
函数中的参数是指向元素的指针。所以你需要添加正确的类型转换然后取消引用指针:
const BigramObject objA = *(BigramObject *)a
const BigramObject objB = *(BigramObject *)b;
我正在编写一个对“二元数组”进行排序的程序。基本上,我有一个包含 BigramObjects 的数组。每个对象都包含一个“count”和“bigram”。我想按“计数”的顺序对我的二元数组进行排序。下面是我试图用来解决这个问题的代码。
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "bigramArray.h"
typedef struct bigramObject *BigramObject;
struct bigramObject {
char *bigram;
int count;
};
struct bigramArray {
BigramObject *data;
int size;
};
#define NUMBER_OF_CHARACTERS (256)
BigramArray bigramArrayCreate(void) {
BigramArray b = malloc(sizeof(struct bigramArray));
assert(b);
b->size = NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS;
b->data = malloc(sizeof(struct bigramObject) * NUMBER_OF_CHARACTERS * NUMBER_OF_CHARACTERS);
assert(b->data);
for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
BigramObject obj = malloc(sizeof(struct bigramObject));
assert(obj);
//Store the bigram for this cell
obj->bigram = malloc(sizeof(char) * 2);
assert(obj->bigram);
obj->bigram[0] = i;
obj->bigram[1] = j;
obj->count = 0;
b->data[i * NUMBER_OF_CHARACTERS + j] = obj;
}
}
return b;
}
void bigramArrayDestroy(BigramArray b) {
for(int i = 0; i < NUMBER_OF_CHARACTERS; i++) {
for(int j = 0; j < NUMBER_OF_CHARACTERS; j++) {
free(b->data[i * NUMBER_OF_CHARACTERS + j]->bigram);
free(b->data[i * NUMBER_OF_CHARACTERS + j]);
}
}
free(b->data);
free(b);
}
int compare(const void *a, const void *b) {
const BigramObject objA = (BigramObject) a;
const BigramObject objB = (BigramObject) b;
return objA->count - objB->count;
}
void sortBigramArray(BigramArray b) {
// UP TO HERE IS GOOD
qsort(b->data, b->size, sizeof(BigramObject), compare);
}
但是,当我测试排序时,程序根本不对任何内容进行排序。我有 运行 gdb 在一个完全普通的二元数组上(基本上所有的计数都是 0),我注意到 objA 和 objB 的计数都不是 0(它们更接近像 4215872 这样的数字并且有差异在我逐步完成一些之后是二的倍数)。在 sortBigramArray 函数中,所有计数仍然为 0。有人可以向我解释为什么会发生这种变化吗?
compare
函数中的参数是指向元素的指针。所以你需要添加正确的类型转换然后取消引用指针:
const BigramObject objA = *(BigramObject *)a
const BigramObject objB = *(BigramObject *)b;