在结构中按频率对数组中的字母进行排序

Posted

技术标签:

【中文标题】在结构中按频率对数组中的字母进行排序【英文标题】:Sorting letters in an array by frequency in within a struct 【发布时间】:2021-04-28 16:39:49 【问题描述】:

我正在尝试按字符串中的频率对字母进行排序。如果两个或多个字母的频率相同,则频率相同的字母将按字母顺序排序。

这是我到目前为止所取得的成果

void get_text_statistics(const char *text, size_t len, statistics_t *data)

    *data = (statistics_t)
        
            .sentences          = count_sentences(text, len),
            .words              = count_words(text, len),
            .most_freq_chars    = /*something needs to be here*/
        

        get_letter_frequencies(text, len, &data -> freq[0], &data -> max_freq)

如您所见,我的问题是尝试按频率对字符串中的字母进行排序。我尝试查找一些教程,但找不到与此特定示例类似的内容。这是相关的结构。

typedef struct statistics

    char_counts_t char_info;
    int sentences;
    int words;
    int freq[26];
    int max_freq;
    char most_freq_chars[27];
 statistics_t;

早些时候,我设法制作了这个可能有帮助的功能。

void get_letter_frequencies(const char *text, size_t len, int freq[26], int *max_freq)


    for (int i = 0; i < 26; i++)
        freq[i] = 0;

    for (int i = 0; i < len; i++) 
        if ((text[i] >= 97) && (text[i] <= 122))
            freq[text[i] - 97]++;

    *max_freq = 0;
    for (int i = 0; i < 26; i++)
        if (*max_freq < freq[i])
            *max_freq = freq[i];

我该怎么做呢? TIA

p.s:count_sentencescount_words 是对字符串中的句子和单词进行计数的函数。

【问题讨论】:

请阅读How to Ask并发布minimal reproducible example。看来您应该首先对频率值进行排序,然后如果它们匹配,则对代码点进行排序。请定义most_freq_chars 应该是什么。我们谈论的是前 3 名、前 10 名还是前 20 名?它是一个字母数组吗?我们不是代码编写服务。编写MostFrequentChars(...)函数,如果遇到困难,请发布MCVE。 @jwdonahue 抱歉,我忘了包含相关的结构。 most_freq_chars 构成了现在包含在问题本身中的结构的一部分。 most_freq_chars 是一个由 26 个小写字母组成的数组(26 个字母,因为字母表中有 26 个字母) most_freq_chars 要求您根据频率降序对字符进行排序。如果是我,我会在 get_letter_frequencies 中添加一个字母和频率结构的数组,然后对其进行降序排序,然后将该数据传输到 most_freq_chars。 这样的:onlinegdb.com/HyPmZtoyO 【参考方案1】:

我想到的一个解决方案是创建一个同时包含字符和频率的结构,并使用带有自定义比较功能的qsort 进行排序。这样频率限制是 INT_MAX。

一种更老套的方法是对整数数组进行排序,对每个毒药使用freq*128 + ('a' + i),使用greater 进行普通整数数组排序,然后使用most_freq_chars = freq_array[i]%128 获取字符

希望对你有帮助=]

#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort */
#include <string.h>     /* strlen */

typedef struct freq_pair 
  char c;
  int freq;
 freq_pair_t;

typedef struct statistics 
  char_counts_t char_info;
  int sentences;
  int words;
  int freq[26];
  int max_freq;
  char most_freq_chars[26]; // You don't need 27 spaces here
 statistics_t;

void get_letter_frequencies(const char* text, size_t len, int freq[26], int* max_freq) 
  for (int i = 0; i < 26; i++) 
    freq[i] = 0;
  

  for (int i = 0; i < len; i++) 
    if ((text[i] >= 'a') && (text[i] <= 'z')) 
      freq[text[i] - 'a']++;
    
  

  *max_freq = 0;
  for (int i = 0; i < 26; i++) 
    if (*max_freq < freq[i]) 
      *max_freq = freq[i];
    
  


int compare(const void* a, const void* b) 
  freq_pair_t* pa = (freq_pair_t*)a;
  freq_pair_t* pb = (freq_pair_t*)b;

  if (pa->freq > pb->freq) 
    return -1;
  

  if (pa->freq == pb->freq) 
    if (pa->c < pb->c) 
      return -1;
    
    if (pa->c > pb->c) 
      return 1;
    

    return 0;
  

  if (pa->freq < pb->freq) 
    return 1;
  


void get_text_statistics(const char* text, size_t len, statistics_t* data) 
  *data = (statistics_t)
      .sentences = count_sentences(text, len),
      .words = count_words(text, len),
      /* Do not init most_freq_chars here, let it for after you calc all the frequencies */
  ;

  get_letter_frequencies(text, len, &data->freq[0], &data->max_freq);
  freq_pair_t freq_pairs[26];

  for (int i = 0; i < 26; i++) 
    freq_pairs[i].freq = data->freq[i];
    freq_pairs[i].c = 'a' + i;
  

  qsort(freq_pairs, 26, sizeof(freq_pair_t), compare);
  for (int i = 0; i < 26; i++) 
    data->most_freq_chars[i] = freq_pairs[i].c;
  


int main() 
  char* s = "quero mudar o mundo, cruzar os ceus sem nada temer";
  statistics_t data;
  get_text_statistics(s, strlen(s), &data);

  for (int i = 0; i < 26; i++) 
    printf("%c ", data.most_freq_chars[i]);
  
  printf("\n");

  for (int i = 0; i < 26; i++) 
    printf("%c-%d ", 'a' + i, data.freq[i]);
  
  printf("\n");

【讨论】:

啊,是的,没想到!但是,除了创建另一个结构之外,还有其他方法吗?另外,关于比较功能,我不能为了简单起见而使用它吗?:onlinegdb.com/HyKBuKn1d 有很多方法可以编写这个比较函数:p 嗯,在 c++ 中我会使用 lambda 函数。除此之外,我只能考虑使用带有频率的全局数组,因此您可以在比较函数中使用它。

以上是关于在结构中按频率对数组中的字母进行排序的主要内容,如果未能解决你的问题,请参考以下文章

我需要帮助以这种特殊方式根据频率对 java 中的数组进行排序

如何在 React.js 中按字母顺序对数组中的对象进行排序

数据结构与算法——计数排序桶排序基数排序

通过降低出现频率对元素进行排序

算法按频率高低来进行排序

如何在 iOS 中按字母顺序对 MediaQuery 的 ArtistQuery 数组进行排序