在结构中按频率对数组中的字母进行排序
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_sentences
和 count_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 中的数组进行排序