如何统计C语言字符串数组中相同长度的单词数量
问题描述
我正在读取一个字典文件,统计文件中的单词总数,并将每个单词存储到字符串数组中。之后我使用qsort()函数对单词先按长度排序,长度相同时按字母序排序。目前我需要统计数组中相同长度的单词数量,期望输出格式如下:
4 letters words: 2018 5 letters words: 170 6 letters words: 10 (...)
现有代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STR 100 /* Sorting the words by length and alphabtichal order, being legnth priority number one */ int compare(const void *a, const void *b){ const char **str_a = (const char **)a; const char **str_b = (const char **)b; int len1 = strlen(*str_a); int len2 = strlen(*str_b); if (len1 < len2) return -1; if (len1 > len2) return 1; return strcmp(*str_a, *str_b); } int main (int argc, char *argv[]){ FILE *fp = NULL; int i = 0, n_total_palavras = 0; char str[MAX_STR]; int count = 0; char **Words; fp = fopen("words.dict", "r"); if (fp == NULL){ exit (0); } while (fscanf(fp,"%s",str) == 1){ n_total_palavras++; } Words = (char **)malloc(n_total_palavras * sizeof (char *)); if (Words == NULL){ exit(0); } for (i = 0; i < n_total_palavras; i++){ Words[i] = NULL; } rewind (fp); while (fscanf(fp,"%s",str) == 1){ Words[count] = (char*)malloc((strlen(str)+1) * sizeof(char)); strcpy(Words[count], str); count++; } qsort(Words, n_total_palavras, sizeof(Words[0]), compare); /* for(i = 0; i < n_total_palavras; i++){ printf("%s\n", Words[i]); } */ fclose(fp); return 0; }
请问该如何实现统计相同长度单词数量的功能?
解决方案
由于已经通过qsort()将单词按长度升序排列,相同长度的单词会连续分布,只需一次遍历就能完成统计:
实现步骤
在qsort()执行完毕后、fclose(fp)之前插入以下代码:
if (n_total_palavras == 0) { fclose(fp); return 0; } // 初始化当前统计的单词长度和计数 int current_len = strlen(Words[0]); int current_count = 1; // 从第二个单词开始遍历数组 for (i = 1; i < n_total_palavras; i++) { int curr_word_len = strlen(Words[i]); if (curr_word_len == current_len) { // 长度相同,计数加1 current_count++; } else { // 长度变化,输出上一组统计结果 printf("%d letters words: %d\n", current_len, current_count); // 更新当前统计的长度和计数 current_len = curr_word_len; current_count = 1; } } // 输出最后一组长度的统计结果 printf("%d letters words: %d\n", current_len, current_count);
关键说明
- 先判断总单词数为0的情况,避免空数组访问错误
- 遍历过程中,每次遇到长度变化时,输出之前长度的统计数据并重置计数
- 循环结束后必须输出最后一组数据,因为循环内仅在长度变化时触发输出,最后一组不会触发该逻辑
优化建议
可以在读取单词时同步记录每个单词的长度,避免遍历统计时重复调用strlen():
- 定义一个
int *word_lengths数组,在分配Words内存后同步分配:
int *word_lengths = malloc(n_total_palavras * sizeof(int)); if (word_lengths == NULL) { // 内存分配失败处理逻辑 exit(0); }
- 读取单词时存储长度:
rewind (fp); while (fscanf(fp,"%s",str) == 1){ Words[count] = (char*)malloc((strlen(str)+1) * sizeof(char)); strcpy(Words[count], str); word_lengths[count] = strlen(str); count++; }
- 统计时直接使用
word_lengths数组的值,无需重复计算:
int current_len = word_lengths[0]; // ... int curr_word_len = word_lengths[i];
内容的提问来源于stack exchange,提问作者Userdsnv17
相关产品推荐
相关产品推荐

