sorting 2-d array based on the first column

偶尔善良 提交于 2019-12-24 19:22:28

问题


I have a temp2.dat file that looks like this:

0.060493 1 0.5 1
1.596961 0 0.1 2
0.87758  1 0.3 1.5
0.165453 1 0   3
0.07085  1 0.3 4
0.125379 1 0.2 3
0.454202 1 0.2 2
0.373227 1 0.3 1
0.131486 1 0.3 3
0.867477 0 0.5 4
0.122609 0 0.8 9

Now I want to write the function in C to sort these 4 columns in an increasing order but only based on the values of the first column. I tried modifying the following code but it failed:

struct data_t
{
    double x;
    int y;
    double z;
    double k;
};

int compare(const void *a, const void *b)
{
    const struct data_t *m = a;
    const struct data_t *n = b;
    if(m->x == n->x)
        return m->y > n->y;
        return m->z > n->z;
        return m->k > n->k;
    return m->x > n->x;
}

Could someone please help me do this? The expected result should look like this:

0.060493 1 0.5 1
0.07085  1 0.3 4
0.122609 0 0.8 9
0.125379 1 0.2 3
0.131486 1 0.3 3
................
0.87758  1 0.3 1.5
1.596961 0 0.1 2

回答1:


Try this compare function

int compare(const void *a, const void *b)
{
    const struct data_t *m = a;
    const struct data_t *n = b;

    if(m->x != n->x)
        return (m->x > n->x) - (m->x < n->x);

    if(m->y != n->y)
        return m->y - n->y;

    if(m->z != n->z)
        return (m->z > n->z) - (m->z < n->z);

    if(m->k != n->k)
        return (m->k > n->k) - (m->x < n->k);

    return 0;
}

This will compare the first column x. If x is the same in the two elements, it moves to the second column y. If the second column is the same, it moves to the third column and so on.

We want the difference between the two values. Example, m->y - n->y. The compare function should return an integer value 0, negative, or positive.

When comparing double values, we cannot use m->x - n->x, because the return value for compare is int. We use a comparison function instead.

Testing

struct data_t
{
    double x;
    int y;
    double z;
    double k;
};

int compare(const void *a, const void *b)
{
    const struct data_t *m = a;
    const struct data_t *n = b;

    if(m->x != n->x)
        return (m->x > n->x) ? 1 : -1;

    if(m->y != n->y)
        return m->y - n->y;

    if(m->z != n->z)
        return (m->z > n->z) ? 1 : -1;

    if(m->k != n->k)
        return (m->k > n->k) ? 1 : -1;

    return 0;
}

int main(void)
{
    struct data_t data[] = 
    { 
        { 0.060493, 3, 0.4, 7 },//1st column is the same
        { 0.060493, 2, 0.5, 8 },
        { 0.060493, 1, 0.6, 9 },

        { 0.060493, 3, 0.3, 4 },//1st & 2nd columns are the same
        { 0.060493, 3, 0.2, 5 },
        { 0.060493, 3, 0.1, 6 },

        { 0.060493, 1, 0.5, 3 },//1st & 2nd & 3rd columns are the same
        { 0.060493, 1, 0.5, 2 },
        { 0.060493, 1, 0.5, 1 },

        { 0.122609, 0, 0.8, 9 },
        { 0.125379, 1, 0.2, 3 },
        { 0.131486, 1, 0.3, 3 },
    };

    int count = sizeof(data) / sizeof(data[0]);
    qsort(data, count, sizeof(data[0]), compare);

    for(int i = 0; i < count; i++)
    {
        printf("%.6f %d %.1f %.0f\n",
            data[i].x, data[i].y, data[i].z, data[i].k);
    }

    return 0;
}

output:

0.060493 1 0.5 1
0.060493 1 0.5 2
0.060493 1 0.5 3
0.060493 1 0.6 9
0.060493 2 0.5 8
0.060493 3 0.1 6
0.060493 3 0.2 5
0.060493 3 0.3 4
0.060493 3 0.4 7
0.122609 0 0.8 9
0.125379 1 0.2 3
0.131486 1 0.3 3



回答2:


First off, in C if you want more than one statement inside any block, you have to surround it with { and }. So your last 3 return statements would never be reached (the indentation does not matter for the compiler, only for humans).

Second, when you call return, your code does not come back. So you could use nested ifs to compare the values in case they are the same in some of the columns. Something like:

int compare(const void *a, const void *b)
{
    const struct data_t *m = a;
    const struct data_t *n = b;
    if(m->x == n->x) {
        if (m->y == n->y) {
            if (m->z == n->z) {
                return m->k > n->k;
            }
            return m->z > n->z;
        }
        return m->y > n->y;
    }
    return m->x > n->x;
}


来源:https://stackoverflow.com/questions/49183054/sorting-2-d-array-based-on-the-first-column

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!