【问题标题】:keeping track of the original indices of an array after sorting in C在C中排序后跟踪数组的原始索引
【发布时间】:2014-08-26 12:19:13
【问题描述】:

我有一个数组,比如说A[5],5 个元素是5,4,1,2,3。现在我按升序对这些数组进行排序。所以结果数组现在将是1,2,3,4,5。我使用stdlib.hqsort() 函数对其进行排序。问题是如何获得原始数组相对于我的新数组的索引。最初我的索引是0,1,2,3,4 对应的5,4,1,2,3 值,现在索引已更改为2、3、4、1、0。如何在 C 中有效地获取这些索引?提前谢谢(如果可能请写代码)

【问题讨论】:

  • 不是对数组本身进行排序,而是创建一个索引数组并对 that 进行排序,并使用比较器函数来比较索引值。
  • 你能举个例子吗?这对我来说并不完全清楚
  • 好吧,你想让comp(i, j)返回a[i] < a[j](而不是i < j)等等
  • 你能帮我解决这个问题吗?我将用一个例子来澄清。 5,4,1,2,3 是我未排序的数组。现在我得到了一个索引。让我们取第三个索引,第三个索引的值是 2。现在我必须在数组排序后找到值 2 的索引。我该怎么做?

标签: c arrays sorting qsort


【解决方案1】:

在有限的条件下还有如下方法。

#include <stdio.h>

int main(void){
    int data[] ={ 5,4,1,2,3 }; //Without duplication, The number of limited range.
    int size = sizeof(data)/sizeof(*data);
    int keys[size];
    int i;

    printf("data :\n");
    for(i=0;i<size;i++){
        printf("%d ",data[i]);
    }
    for(i=0;i<size;i++){
        keys[data[i]-1]=i;
    }

    printf("\n\ndata\tindex\n");
    for(i=0;i<size;i++){
        printf("%d\t%d\n", data[keys[i]], keys[i]);
    }
    return 0;
}
/* result sample
data :
5 4 1 2 3

data    index
1       2
2       3
3       4
4       1
5       0
*/

建议如何对索引数组@Kerrek 进行排序。

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

int *array;

int cmp(const void *a, const void *b){
    int ia = *(int *)a;
    int ib = *(int *)b;
    return array[ia] < array[ib] ? -1 : array[ia] > array[ib];
}

int main(void){
    int data[] ={ 5,4,1,2,3 };
    int size = sizeof(data)/sizeof(*data);
    int index[size];//use malloc to large size array
    int i;

    for(i=0;i<size;i++){
        index[i] = i;
    }
    array = data;
    qsort(index, size, sizeof(*index), cmp);
    printf("\n\ndata\tindex\n");
    for(i=0;i<size;i++){
        printf("%d\t%d\n", data[index[i]], index[i]);
    }
    return 0;
}

【讨论】:

  • 限制是多少?我可以将此方法用于数组中的 10^5 个元素吗?我的整数的最大大小是 10^9。
  • @user3807678 我认为这可能是Kerrek 之类的一般建议。我已经添加了示例代码。
  • 非常感谢您的代码!我已经获得了一个值的旧索引,我必须在排序数组中找到该值的新索引。我们如何在同一个例子中做到这一点?
  • @user3807678 我不知道你在说什么。你想要i吗?
  • 我会用一个例子来说明。 5,4,1,2,3 是我未排序的数组。现在我得到了一个索引。让我们取第三个索引,第三个索引的值是 2。现在我必须在数组排序后找到值 2 的索引。我该怎么做?
【解决方案2】:

获取一个二维数组。将数字存储在第一列,然后将相应的索引存储在第二列。您可以将比较器函数编写为:

int compare ( const void *pa, const void *pb ) 
{
    const int *a = pa;
    const int *b = pb;
    if(a[0] == b[0])
        return a[1] - b[1];
    else
        return a[0] - b[0];
}  

致电qsort 应为:

qsort(array, n, sizeof array[0], compare);  // n is representing rows  

Live Demo

【讨论】:

    【解决方案3】:
    #include <limits.h>
    #include <stdio.h>
    #define SIZE 5
    int* sortArrayNKeepIndices(int arr[], int arrSize){
        static int indexArr[SIZE];
        int arr2[arrSize];
        for (int i = 0; i < arrSize; i++) {
            indexArr[i] = 0;
            arr2[i] = arr[i];
        }
        int min = 0, temp = 0;
    
        for (int i = 0; i < arrSize ; i++)
        {
            min = i;  // record the position of the smallest
            for (int j = i + 1; j < arrSize; j++)
            {
                // update min when finding a smaller element
                if (arr[j] < arr[min])
                    min = j;
            }
            // put the smallest element at position i
            temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        } // array sorting ends here
        int ctr = 0;
        while ( ctr < arrSize) {
            min = 0;  // restart from first element
            for (int j = 0; j < arrSize; j++)
            {
                if (arr2[j] == INT_MAX) continue; // ignore already marked as minimum indices
                // update min when finding a smaller element
                if (arr2[j] < arr2[min])
                    min = j;
            }
            indexArr[ctr] = min; // updating indexArr with the index of the next minimum
            arr2[min] = INT_MAX; // marking minimum element to be ignored next time
            ctr++;
        } //keeping track of previous indices of the array elements ends here
        return indexArr;
    } // function sortArrayKeepIndices ends here
    int main () {
        int arr[SIZE] = {16, 15, 12, 10, 13};
        int* ptr = sortArrayNKeepIndices(arr, SIZE);
        for (int dex = 0; dex < SIZE; dex++){
            printf("%d (%d, %d)\t", arr[dex], * (ptr + dex), dex);}
    }
    

    // 输出将是 10 (3, 0) 12 (2, 1) 13 (4, 2) 15 (1, 3) 16 (0, 4) // 元素(旧索引,新索引)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 2012-05-21
      • 2013-04-27
      相关资源
      最近更新 更多