【问题标题】:How can I get the sorting permutation of an array?如何获得数组的排序排列?
【发布时间】:2021-07-26 05:26:23
【问题描述】:

我有一个 k 整数数组,我想从最大到最小整数进行排序。但是,我希望它“记住”未排序数组的原始索引。 (注意:我是用 C 语言编程的)。

在我的示例中,我有一个由 26 个元素组成的数组,它们表示文本文件中字母表中出现的字母。所以,第一个元素是“a”在文本中出现的次数,第二个元素是“b”出现的次数,以此类推……

我想以这样一种方式对数组进行排序,以便我可以获得从最常见到最不常见的字母出现的统计信息。

现在,我想到了两种可能的方法:

  1. 使用 26x2 二维数组,其中第一列中的字母索引和第二列中的出现次数。通过仅按第二列排序,我将得到一个 26x2 数组,该数组按我想要的顺序排列,但我不知道索引是否仍会与字母的出现相关联(我不知道知道如何实现这一点)。

  2. 我正在考虑的另一个选项是以某种方式生成 26 个索引的排列,这将在不实际排序的情况下对数组进行排序。通过这种方式,我可以将这个“排列数组”与我的无序数组进行比较,并找出最常见的字母。但是我不知道C中是否存在这样的功能。

有人能告诉我他们将如何解决这个问题吗?即使使用伪代码,只要您让我知道函数的调用方式以及定义它们的库即可。非常感谢!

【问题讨论】:

  • 我在这里看不到任何代码...您是否尝试了两种可能的方法中的任何一种?结果如何?
  • @g01d:堆栈溢出问题通常不需要代码。调试问题应该提供代码,但算法和方法的问题一般不需要代码。

标签: arrays c function sorting multidimensional-array


【解决方案1】:

您可以使用第一个选项的变体来做到这一点。

定义一个包含两个字段的结构:一个计数和该计数的相关字母。按顺序用字母创建这些结构的数组并填充计数。然后根据计数字段对结构数组进行排序。您将得到按计数而不是按字母排序的结构。

【讨论】:

    【解决方案2】:

    您确实使用了带有计数和字母的结构数组,并使用适当的比较函数对该数组进行排序。

    或者,您可以将计数和字母组合成一个数字:

    int a[26];
    ...
    
    for (int i = 0; i < 26; i++) {
        a[i] = a[i] * 26 + i;
    }
    

    然后您可以对这个 int 数组进行排序,并打印计数和字母值:

    qsort(a, 26, sizeof(*a), cmp_int);
    
    for (i = 0; i < 26; i++) {
        printf("%c: %d\n", 'A' + a[i] % 26, a[i] / 26);
    }
    

    降序排序的比较函数:

    int cmp_int(const void *a, const void *b) {
        int aa = *(const int **)a;
        int bb = *(const int **)b;
        return (aa < bb) - (aa > bb);
    }
    

    【讨论】:

      【解决方案3】:

      对于 26 个小整数,计算时间和资源一般可以忽略不计,所以代码应该写得简单明了。如果qsort 接受它传递给比较例程的上下文,我建议将索引数组排序到计数数组中。但是,这需要知道count 数组在哪里,我们无法通过qsort。另一种方法是对指向计数的指针进行排序:

      #include <stdio.h>
      #include <stdlib.h>
      
      
      #define N   26
      
      
      //  Compare the counts of the letters pointed to indirectly.
      static int compare(const void *va, const void *vb)
      {
          const int * const *pa = va, * const *pb = vb;
          int a = **pa, b = **pb;
          return
              a <  b ? -1 :
              a == b ?  0 :
                       +1;
      }
      
      
      int main(void)
      {
          srand(0);
      
          int count[N];
          for (size_t i = 0; i < N; ++i) count[i] = rand();
      
          //  Initialize an array of pointers into count.
          int *pointer[N];
          for (size_t i = 0; i < N; ++i) pointer[i] = &count[i];
      
          //  Sort the pointers.
          qsort(pointer, N, sizeof *pointer, compare);
      
          //  Print the letters and their counts in order from the sorted pointers.
          for (size_t i = 0; i < N; ++i)
              printf("%c appears %d times.\n",
                  (int) ('a' + (pointer[i] - count)), *pointer[i]);
          //  (ASCII is assumed.)
      }
      

      请注意,因为pointer[i] 指向count 数组,我们可以使用pointer[i] - count 恢复字母的索引。 (解释为什么 'a' + (index[i] - count) 被转换为 int 的奖励积分。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-18
        • 2019-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-24
        相关资源
        最近更新 更多