【问题标题】:How to obtain the descending order (ordinality) of an integer array?如何获取整数数组的降序(序数)?
【发布时间】:2013-10-04 22:12:14
【问题描述】:

我需要查找整数数组中元素的降序。

例子:

如果我有一个数组:

x = {24, 55, 22, 1}

我想要一个 C 中的算法,它产生数组 order,其中:

order = {2, 1, 3, 4}

考虑到“我的”数组x 可能变得相当大(从1k-1M),我的问题如下:如何尽可能高效(快速)地获得order 数组? 显然必须存在一种有效的算法来做到这一点?

【问题讨论】:

  • “向量”是指数组吗? C++ 在其标准库中有一个类型vector; C 没有。 (gcc 还有一个不相关的扩展名为vectors,与C++ 的std::vector 无关。)
  • 我的意思当然是数组。对不起,如果我不清楚。

标签: c arrays algorithm sorting


【解决方案1】:

我想更有效的方法是最知名的方法。例如:

  • 为从 0 到 N-1 的所有索引分配一个向量并初始化它
  • 使用一种有效的排序算法(例如quicksortmerge sort)对索引向量进行排序,但要参考原始数据向量(对索引进行排序,然后比较原始数据)

【讨论】:

  • 好答案。只是添加一些额外的信息:这个方法是 O(n*log(n)),它不能比这更好,因为它受排序操作的限制。
  • @FilipeGonçalves - 您是如何确定这种效率等级的? (即O(n*log(n))。你有链接吗?
  • @ryyker 好吧,由于快速排序和归并排序都在 O(n*log(n)) 中运行,这就是整个算法的复杂性...
【解决方案2】:

您可以使用 qsort 标准函数的比较器函数: http://www.tutorialspoint.com/c_standard_library/c_function_qsort.htm 只需实现你的比较器来添加一个间接,即替换:

return ( *(int*)a - *(int*)b );

通过

return (x[*(int*)b] - x[*(int*)a]);

(编辑以获取降序)

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

int x[] = { 88, 56, 100, 2, 25 };
int indexes[] = { 0, 1, 2, 3, 4};

int cmpfunc (const void * a, const void * b)
{
   return ( x[*(int*)b] - x[*(int*)a] );
}

int main()
{
   int n;

   printf("Before sorting the list is: \n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", indexes[n]);
   }

   qsort(indexes, 5, sizeof(int), cmpfunc);

   printf("\nAfter sorting the list is: \n");
   for( n = 0 ; n < 5; n++ ) {
      printf("%d ", indexes[n]);
   }

  return(0);
}

【讨论】:

  • 您能否详细说明一下,因为我在示例代码上测试它时没有让它工作?
  • 谢谢,我明白了。举个例子总是有帮助的。
  • qsort 比较函数中使用减法,如return ( *(int*)a - *(int*)b );,可能会出现溢出问题(考虑a 是一个大的负数而b 是一个大的正数)。
【解决方案3】:

我将从 stdlib.h 中的qsort 开始 由于它需要一个指向函数的指针,因此不会是最快的,但肯定是更容易编码。

int v[4] = {24, 55, 22, 1};
int fcmp(const void *a, const void *b) {
    int A = *(const int*)a;
    int B = *(const int*)b;
    if (v[A] > v[B]) return -1;
    if (v[A] < v[B]) return +1;
    return 0;
}

int main(int argc, char *argv[])
{
    int r[4] = {0, 1, 2, 3 };
    qsort(r, 4, sizeof(int), fcmp);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    • 2015-11-01
    • 2014-10-14
    • 2019-09-08
    • 1970-01-01
    • 2022-01-05
    • 2023-04-02
    相关资源
    最近更新 更多