簡體   English   中英

按C中的第一列對動態分配的2D數組進行排序

[英]Sort dynamically allocated 2D array by first column in C

我有一個較大的2D雙打數組,我想按第一列進行排序。 陣列較大(2GB)時,需要動態分配內存。

以下是我的破損代碼的簡化示例,出於示例目的使用隨機數。

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

int Double_Compare_Function ();

int main()
{
    srand(time(0));
    int p = 0; //property index
    int number_properties = 6; // number_properties
    long long n = 0; //node index
    long long number_nodes = 5; //number of nodes

    /* Declare array */
    double **properties_array;
    properties_array = malloc(number_nodes * sizeof(double*));
    for (n=0; n<number_nodes; n++) {
        properties_array[n] = malloc(number_properties * sizeof(double));
    }

    /* Fill array with numbers */
    for (n=0; n<number_nodes; n++) {
        for (p=0; p<number_properties; p++) {
            properties_array[n][p] = rand();
        }
    }

    printf("Initial array...\n");
    for (n=0; n<number_nodes; n++) {
        printf("%lli: ", n);
        for (p=0; p<number_properties; p++){
            printf("%.1f ", properties_array[n][p]);
        }
        printf("\n");
    }

    /* Sort array */
    qsort(properties_array, (int)number_nodes, number_properties*sizeof(double), Double_Compare_Function);

    printf("Sorted array...\n");
    for (n=0; n<number_nodes; n++) {
        printf("%lli: ", n);
        for (p=0; p<number_properties; p++){
            printf("%.1f ", properties_array[n][p]);
        }
        printf("\n");
    }

    return(0);
}

int Double_Compare_Function (const void * a, const void * b) {
    if (*(double*)a > *(double*)b) return 1;
    else if (*(double*)a < *(double*)b) return -1;
    else return 0;
}

產量

程序編譯沒有錯誤(除了隨機數生成警告)。 它似乎指向了我不想要的內存。

Initial array...
0: 17189.0 13476.0 24803.0 23588.0 9169.0 13351.0
1: 20992.0 15638.0 23138.0 8580.0 32516.0 24064.0
2: 27139.0 23745.0 19237.0 19279.0 19262.0 25303.0
3: 19407.0 24529.0 23675.0 3102.0 23878.0 5831.0
4: 15299.0 3845.0 27278.0 17467.0 28106.0 6918.0
Sorted array...
0: 17189.0 13476.0 24803.0 23588.0 9169.0 13351.0
1: 19262.0 25303.0 13104405306123376000000000000000000000000.0 0.0 32516.0 24064.0
2: 27139.0 23745.0 1361751537953832600000000000000000000000000000000000000000000000000000.0 0.0 20992.0 15638.0
3: 19407.0 24529.0 23675.0 3102.0 23878.0 5831.0
4: 15299.0 3845.0 27278.0 17467.0 28106.0 6918.0

問題已回答。

您的問題是您無法將由指針到指針組成的對象作為數組進行qsort ,因為沒有要求分配的地址在內存中是連續的。 相反,您需要聲明並分配雙精度數組[number_properties]指針,並在一次調用中分配節點和屬性,以確保對象在內存中是連續的,例如

    /* Declare array */
    double (*properties_array)[6];
    properties_array = malloc(number_nodes * number_properties * sizeof(double));
    if (!properties_array) {
        perror ("malloc-properties_array");
        return 1;
    }

注意:從技術上講,這是雙精度[VLA_VLA]指針,除非使用整數常量來指定number_properties從聲明number_properties的方式尚不清楚,但隨后在代碼中使用了整數常量。請注意,如果您選擇在代碼中使用VLA,則該功能自C11起是實現定義的功能)

現在您的qsort比較可以寫成:

int Double_Compare_Function (const void * a, const void * b) {
    if (*(double * const *)a > *(double * const *)b) return 1;
    else if (*(double * const *)a < *(double * const *)b) return -1;
    else return 0;
}

使用/輸出示例

$ ./bin/doublecmp
Initial array...
0: 2058999144.0 1013160096.0 499880968.0 1375376710.0 1398189150.0 579626176.0
1: 35952305.0 349854458.0 1000340925.0 1397136257.0 2028006902.0 877319625.0
2: 579560718.0 745830077.0 766399485.0 1052819099.0 1279742925.0 80594279.0
3: 390212763.0 603717917.0 1542566382.0 654797188.0 957950686.0 807072250.0
4: 1163825233.0 1748173998.0 261624942.0 152991913.0 269595164.0 2130895736.0
Sorted array...
0: 35952305.0 349854458.0 1000340925.0 1397136257.0 2028006902.0 877319625.0
1: 390212763.0 603717917.0 1542566382.0 654797188.0 957950686.0 807072250.0
2: 579560718.0 745830077.0 766399485.0 1052819099.0 1279742925.0 80594279.0
3: 1163825233.0 1748173998.0 261624942.0 152991913.0 269595164.0 2130895736.0
4: 2058999144.0 1013160096.0 499880968.0 1375376710.0 1398189150.0 579626176.0

速記比較功能

注意,您還可以編寫與條件條件結果的單次返回相同的雙比較函數,例如

int Double_Compare_Function (const void * a, const void * b)
{
    return (*(double * const *)a > *(double * const *)b) -
           (*(double * const *)a < *(double * const *)b);
}

您需要對指針進行排序。

您也缺少#include <time.h>

在下面,我添加了缺少的include,僅將打印限制在數組的第一個元素上,並將rand()輸出限制為% 100 ,因此數字較小。

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

int Double_Compare_Function(const void *, const void *);

int number_properties = 6; // number_properties

int main()
{
    srand(time(0));
    int p = 0; //property index
    long long n = 0; //node index
    long long number_nodes = 5; //number of nodes

    /* Declare array */
    double **properties_array;
    properties_array = malloc(number_nodes * sizeof(double*));
    for (n=0; n<number_nodes; n++) {
        properties_array[n] = malloc(number_properties * sizeof(double));
    }

    /* Fill array with numbers */
    for (n=0; n<number_nodes; n++) {
        for (p=0; p<number_properties; p++) {
            properties_array[n][p] = rand() % 100;
        }
    }

    printf("Initial array...\n");
    for (n=0; n<number_nodes; n++) {
        printf("%lli: ", n);
        for (p=0; p<1; p++){
            printf("%.1f ", properties_array[n][p]);
        }
        printf("\n");
    }

    /* Sort array */
    qsort(properties_array, number_nodes, sizeof(double*),
    Double_Compare_Function);

    printf("Sorted array...\n");
    for (n=0; n<number_nodes; n++) {
        printf("%lli: ", n);
        for (p=0; p<1; p++){
            printf("%.1f ", properties_array[n][p]);
        }
        printf("\n");
    }

    return(0);
}

int Double_Compare_Function (const void * a, const void * b) {
  const double * const *z = a;
  const double * const *y = b;
  // the z is a pointer to an array of doubles
  // let's get the first element
  const double k = (*z)[0];
  const double m = (*y)[0];
  return k > m ? 1 : k < m ? -1 : 0;
}

Double_Compare_Function接收兩個與properties_array類型相同的指針-它是double** 您需要取消引用兩次。 由於每個properties_array元素都指向malloc(number_properties * sizeof(double))返回的值,因此我想使用[0]使其變得冗長,我的意思是數組的第一個元素。 (*z)[0]**z相同。

執行示例:

Initial array...
0: 3.0
1: 94.0
2: 35.0
3: 24.0
4: 71.0
Sorted array...
0: 3.0
1: 24.0
2: 35.0
3: 71.0
4: 94.0

比較的實際參數是double** ,而不是double*
(您將獲得指向每個元素的指針,而不是元素本身的指針。)

如果要對第一個元素進行排序,請使用以下內容:

int Compare_Function (const void * a, const void * b) {
    double* array_a = *(double**)a;
    double* array_b = *(double**)b;
    return (int) (array_a[0] - array_b[0]);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM