使用其他数组排序数组

时间:2016-11-26 00:26:49

标签: c sorting

我尝试使用长度为r的数组来实现一个对长度为DIM*n的数组n进行排序的算法。我不知道我的代码出错了。我没有得到预期的结果。结果应该看起来像填充莫顿曲线的空间。但正如您所看到的,结果包含许多零。我不知道他们来自哪里?你能帮我找一下这个错误吗?这是我的可执行代码:

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

#define DIM 2

// Sort list "r" using list "mInt"
void sort(unsigned int *mInt, double *r, int n){ 
   unsigned int i, j, ph0;
   double ph1, ph2;

   for(i = 1; i <= n-1; i++)
      for(j = 1; j <= n-i; j++)
         if(mInt[j-1] >= mInt[j])
         {
            // 1
            ph1 = r[DIM*(j-1)+0];
            ph2 = r[DIM*(j-1)+1];
            ph0 = mInt[j-1];

            // 2
            mInt[j-1] = mInt[j];
            r[DIM*(j-1)+0] = r[DIM*j+0];
            r[DIM*(j-1)+1] = r[DIM*j+1];

            // 3
            mInt[j] = ph0;
            r[DIM*j+0] = ph1;
            r[DIM*j+1] = ph2;
         }
}

// Create morton key
inline unsigned int mortoncode(unsigned int x, unsigned int y){
    int answer = 0;
    for (unsigned int i = 0; i < (sizeof(unsigned int)* 8)/2; ++i) {
        answer |= (((x & ((unsigned int)1 << i)) << 2*i) | ((y & ((unsigned int)1 << i)) << (2*i + 1)));
    }
    return answer;
}

// Find max / min values
double maxValue(double *r, int n, int d){
    double max = r[d];
    for(int k=0; k<n; k++){
        if(max < r[DIM*k+d]){
            max = r[DIM*k+d];
        }
    }
    return max;
}
double minValue(double *r, int n, int d){
    double min = r[d];
    for(int k=0; k<n; k++){
        if(min > r[DIM*k+d]){
            min = r[DIM*k+d];
        }
    }
    return min;
}

int main(int argc, char **argv){  
    FILE *f = fopen("data.dat", "w"); 
    int n = 100;
    double r[n*DIM];

    // Initialize data
    double x1 = 0;
    double y1 = 0;
    for(int k=0; k<n; k++){
        r[DIM*k+0] = x1;
        r[DIM*k+1] = y1;
        x1 += 0.1;
        if(k % 10 == 0){
            y1 += 0.1;
            x1 = 0;
        }
        printf("%lf %lf\n", r[DIM*k+0], r[DIM*k+1]);
    }

    // Get max/min values
    double rMin[DIM];
    double rMax[DIM];
    for(int d=0; d<DIM; d++){
        rMin[d] = minValue(r, n, d);
        rMax[d] = maxValue(r, n, d);
    }

    // Convert double data to integers
    printf("\n");
    unsigned int rInt[n];
    for(int k=0; k<n; k++){
        for(int d=0; d<DIM; d++){
            int idx=DIM*k+d;
            double map = floor(((2097151)/(rMax[d]-rMin[d]))*r[idx]-rMin[d]);
            rInt[idx] = (int)map;
        }
        printf("%d %d\n", rInt[DIM*k+0], rInt[DIM*k+1]);
    }

    // Convert rInt[x_1,y_1,x_2,y_2,...] to Morton key
    printf("\n");
    unsigned int rMor[n];
    for(int k=0; k<n; k++){
        int idx = DIM*k;
        rMor[k] = mortoncode(rInt[idx+0], rInt[idx+1]);
    }

    // Sort data 
    sort(rMor, r, n);

    for(int k=0; k<n; k++){
        printf("%lf %lf\n", r[DIM*k+0], r[DIM*k+1]);
        fprintf(f, "%lf, %lf\n", r[DIM*k+0], r[DIM*k+1]);

    }

    return 0;
}

1 个答案:

答案 0 :(得分:3)

我相信@BarmakShemirani在六个评论前有答案,你声称:

  

rInt是n * DIM大。

但你写道:

unsigned int rInt[n];

修复此问题,我通过不使用它来测试您的sort()例程,而是将rrMor放入单个结构数组中并在其上调用qsort()。它们基本上产生相同的结果,除了重复的索引,其中一个将它们相对于另一个反转:

           qsort                          your sort
index      r0       r1         index      r0       r1
2456659099 0.400000 0.500000   2456659099 0.400000 1.000000
2456659099 0.400000 1.000000   2456659099 0.400000 0.500000

修改后的代码:

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

#define DIM 2

typedef struct element {
    unsigned int m;
    double r[DIM];
} ELEMENT;

// Sort element structure on member 'm'

int comparator(const void *p, const void *q) {

    ELEMENT *a = (ELEMENT *) p;
    ELEMENT *b = (ELEMENT *) q;

    return (a->m > b->m) - (a->m < b->m); // compare idiom
}

// Create morton key
unsigned int mortoncode(unsigned int x, unsigned int y) {
    int answer = 0;

    for (unsigned int i = 0; i < (sizeof(unsigned int) * 8) / 2; i++) {
        answer |= (((x & (1u << i)) << 2 * i) | ((y & (1u << i)) << (2 * i + 1)));
    }

    return answer;
}

// Find max / min values
double maxValue(ELEMENT data[], int n, int d) {
    double max = data[0].r[d];

    for (int k = 0; k < n; k++) {
        if (max < data[k].r[d]) {
            max = data[k].r[d];
        }
    }

    return max;
}

double minValue(ELEMENT data[], int n, int d) {
    double min = data[0].r[d];

    for (int k = 0; k < n; k++) {
        if (min > data[k].r[d]) {
            min = data[k].r[d];
        }
    }

    return min;
}

int main(int argc, char **argv) {  
    FILE *f = fopen("data.dat", "w"); 
    int n = 100;
    ELEMENT data[n];

    // Initialize data
    double x1 = 0;
    double y1 = 0;

    for (int k = 0; k < n; k++) {
        data[k].r[0] = x1;
        data[k].r[1] = y1;
        x1 += 0.1;
        if (k % 10 == 0) {
            y1 += 0.1;
            x1 = 0;
        }
        printf("%lf %lf\n", data[k].r[0], data[k].r[1]);
    }
    printf("\n");

    // Get max/min values
    double rMin[DIM];
    double rMax[DIM];

    for (int d = 0; d < DIM; d++) {
        rMin[d] = minValue(data, n, d);
        rMax[d] = maxValue(data, n, d);
    }

    // Convert double data to integers

    unsigned int rInt[DIM * n];

    for (int k = 0; k < n; k++) {
        for (int d = 0; d < DIM; d++) {
            int idx = DIM * k + d;
            double map = floor((2097151 / (rMax[d] - rMin[d])) * data[k].r[d] - rMin[d]);
            rInt[idx] = (int) map;
        }

        printf("%d %d\n", rInt[DIM * k + 0], rInt[DIM * k + 1]);
    }
    printf("\n");

    // Convert rInt[x_1, y_1, x_2, y_2, ...] to Morton key

    for (int k = 0; k < n; k++) {
        int idx = DIM * k;
        data[k].m = mortoncode(rInt[idx + 0], rInt[idx + 1]);
    }

    // Sort data 
    qsort(data, n, sizeof(ELEMENT), comparator);

    for (int k = 0; k < n; k++) {
        printf("%u %lf %lf\n", data[k].m, data[k].r[0], data[k].r[1]);
        fprintf(f, "%lf, %lf\n", data[k].r[0], data[k].r[1]);
    }

    return 0;
}

每当您发现自己创建rrMor等并行数组时,通常都会表明您缺少真正的数据结构。