我想在C中使用qsort()对二元数组进行排序。数组包含三维点数据,它是使用fscanf从文件读入的。我的编程技巧是相当有限的,但我有非常大的数据集,我需要处理。如果我的代码很糟糕,请提前抱歉。c中的多维数组的qsort导致段错误
23127.947,23127.947,23127.947
523127.790,523127.790,523127.790
523127.747,523127.747,523127.747
523127.761,523127.761,523127.761
523127.768,523127.768,523127.768
(...为3158632点)
我已经使用printf来隔离我的代码中的问题似乎是导致分段错误的qsort()行。从我读过的Stack Overflow的其他问题可以看出,我的“比较”函数可能会出现问题。做一维数组的例子看起来很简单,但我看到的二维数组的例子并没有进入比较其他维度(先是X,那么如果X1 = X2,比较Y,那么如果Y1 = Y2,则比较Z)。
int main(int argc, char *argv[]) {
int i,j,c;
double x,y,z;
int ROWS = 3158632;
int COLS = 3;
char buffer[100];
double** data = Make2DDoubleArray(ROWS, COLS);
//Open the plot file to read in, and have an output write file
FILE *fp = fopen("Plot_1-2.txt","r");
if(fp == NULL) {
printf("Can't open file\n");
exit;
}
fgets(buffer, 100, fp); //Ignore header
for(i=0; ; i++){
if ((c = fgetc(fp)) == EOF){
break;
}
fscanf(fp,"%lf, %lf, %lf",&x, &y, &z);
data[i][0] = x;
data[i][1] = y;
data[i][2] = z;
}
printf("First 5 unsorted numbers:\n");
for(j=0;j<5;j++){
printf("Line %d: %.3lf, %.3lf, %.3lf\n",j, data[j][0], data[j][0], data[j][0]);
}
printf("Last 5 unsorted numbers:\n");
for(j=ROWS-5;j<ROWS;j++){
printf("Line %d: %.3lf, %.3lf, %.3lf\n",j, data[j][0], data[j][0], data[j][0]);
}
/* Sort array using Quicksort algorithm: */
printf("Sorting...\n");
qsort(data, ROWS, COLS*sizeof(double), &compare);
printf("First 10 sorted numbers:\n");
for(j=0;j<10;j++){
printf("Line %d: %.3lf, %.3lf, %.3lf\n",j, data[j][0], data[j][0], data[j][0]);
}
fclose(fp);
for (i=0; i<ROWS; i++){
free(data[i]);
}
free(data);
return 0;
}
double** Make2DDoubleArray(int arraySizeX, int arraySizeY) {
double** theArray;
int i;
theArray = (double**) malloc(arraySizeX*sizeof(double*));
for (i = 0; i < arraySizeX; i++)
theArray[i] = (double*) malloc(arraySizeY*sizeof(double));
return theArray;
}
int compare(const void *arg1, const void *arg2) {
//double a, b, c, d, e, f;
double *a = (double*)arg1;
double *b = (double*)arg2;
double *c = ((double*)arg1 + 1);
double *d = ((double*)arg2 + 1);
double *e = ((double*)arg1 + 2);
double *f = ((double*)arg2 + 2);
if(a > b)
return 1;
else if(a < b)
return -1;
else {
if(c > d)
return 1;
else if(c < d)
return -1;
else {
if(e > f)
return 1;
else if(e < f)
return -1;
else
return 0;
}
}
}
我想知道如果告诉快速排序去“COLS *的sizeof(双)”是错误的方式与我如何分配给二维数组的存储办呢?将这个问题视为一维数组会使其余部分工作吗?如果可能的话,我宁愿将它保留为二维数组。
感谢您的帮助。我没有粘贴标题,因为我试图削减一下我放在这里的多少。将来我会包括这一点。你认为保持二维数组最好,还是应该创建一个像SpacedMonkey这样的点结构? – 2013-04-23 22:53:41
@PeterOlsoy类型都是一样的。对于内部文档,数组会更具体(“最好”)。详细说明:遵循'double(*)'比'struct ...'更容易,因为在知道它存储的类型/成员之前,必须返回并查找结构。如果其中一个对象的类型发生了变化,那么你可能会想要使用'struct'和'union'。 – Sebivor 2013-04-23 23:01:40
谢谢!这就像一个魅力。它不喜欢后面的int从int到size_t的变化,所以我刚刚摆脱了重新初始化(保持int状态)。我有两个最后的问题,(1)你为什么要将一堆int改成size_t,是有益处还是更多是风格选择? (2)当我使用gcc进行编译时,它给了我一个警告“In function'compare':warning:initialize discards'const'qualifier from pointer target type [默认启用]”,是我应该修复的东西吗?它似乎运行良好。 – 2013-04-24 14:18:20