免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11232 | 回复: 11
打印 上一主题 下一主题

[算法] C语言 词频统计 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-17 16:21 |只看该作者 |正序浏览
任意一段英文,写一个算法,统计这段英文中的任意单词的词频,并按频率高低顺序打印出来。
想了半天没写出来,新人求高人指点

论坛徽章:
0
12 [报告]
发表于 2013-09-20 17:36 |只看该作者
回复 11# cobras


    哇!辛苦了。我读这估计比较困难。我来仔细读读

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
11 [报告]
发表于 2013-09-20 08:56 |只看该作者
下面的算法按空格分词。
  1. #include <ctype.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>

  5. #define MAX_WORD_TYPE       1024
  6. #define FILE_NAME           "cntword.c"

  7. struct word
  8. {
  9.         const char *word;
  10.         int word_len;
  11.         int count;
  12. };

  13. char *read_file(const char *file, int *o_len)
  14. {
  15.         FILE *fp;
  16.         char *buf;
  17.         long len;

  18.         fp = fopen(file, "rb");
  19.         if (fp != NULL) {
  20.                 fseek(fp, 0, SEEK_END);
  21.                 len = ftell(fp);
  22.                 fseek(fp, 0, SEEK_SET);
  23.                 buf = (char *)malloc(len);
  24.                 if (buf != NULL) {
  25.                         if (fread(buf, len, 1, fp) == 1) {
  26.                                 *o_len = len;
  27.                                 fclose(fp);
  28.                                 return buf;
  29.                         }
  30.                         free(buf);
  31.                 }
  32.                 fclose(fp);
  33.         }
  34.         return NULL;
  35. }

  36. int nstr_ltrim(const char *s, int off, int lmt)
  37. {
  38.         int i;

  39.         for (i = off; i < lmt; ++i) {
  40.                 if (!isspace(s[i])) {
  41.                         break;
  42.                 }
  43.         }
  44.         return i;
  45. }

  46. int nstr_get_next_space(const char *s, int off, int lmt)
  47. {
  48.         int i;
  49.        
  50.         for (i = off; i < lmt; ++i) {
  51.                 if (isspace(s[i])) {
  52.                         break;
  53.                 }
  54.         }
  55.         return i;
  56. }

  57. int get_word(const char *s, int *io_off, int lmt, int *o_word_off, int *o_word_lmt)
  58. {
  59.         int off;
  60.         int word_off;
  61.         int word_lmt;

  62.         off = *io_off;
  63.         off = nstr_ltrim(s, off, lmt);
  64.         if (off < lmt) {
  65.                 word_off = off;
  66.                 off = nstr_get_next_space(s, off, lmt);
  67.                 word_lmt = off;
  68.                 *io_off = off;
  69.                 *o_word_off = word_off;
  70.                 *o_word_lmt = word_lmt;
  71.                 return 0;
  72.         }
  73.         return -1;
  74. }

  75. int add_word(struct word *table, int table_len, const char *word, int word_len)
  76. {
  77.         int i;

  78.         for (i = 0; i < table_len; ++i) {
  79.                 if (table[i].word == NULL) {
  80.                         break;
  81.                 }
  82.                 if (table[i].word_len == word_len && strncmp(table[i].word, word, word_len) == 0) {
  83.                         ++table[i].count;
  84.                         return 0;
  85.                 }
  86.         }
  87.         if (i < table_len) {
  88.                 table[i].word = word;
  89.                 table[i].word_len = word_len;
  90.                 table[i].count = 1;
  91.                 return 0;
  92.         }
  93.         return -1;
  94. }

  95. int count_word(char *file, int file_len, struct word *table, int table_len)
  96. {
  97.         int file_off;
  98.         int word_off, word_lmt;

  99.         file_off = 0;
  100.         while (get_word(file, &file_off, file_len, &word_off, &word_lmt) == 0) {
  101.                 add_word(table, table_len, file + word_off, word_lmt - word_off);
  102.         }
  103.         return 0;
  104. }

  105. int print_word(struct word *table, int table_len)
  106. {
  107.         int i;

  108.         for (i = 0; i < table_len; ++i) {
  109.                 if (table[i].word == NULL) {
  110.                         break;
  111.                 }
  112.                 fwrite(table[i].word, 1, table[i].word_len, stdout);
  113.                 printf(": %d\n", table[i].count);
  114.         }
  115.         return 0;
  116. }

  117. int get_table_len(struct word *table, int table_len)
  118. {
  119.         int i;

  120.         for (i = 0; i < table_len; ++i) {
  121.                 if (table[i].word == NULL) {
  122.                         break;
  123.                 }
  124.         }
  125.         return i;
  126. }

  127. int compare_word(const struct word *word1, const struct word *word2)
  128. {
  129.         if (word1->count < word2->count) {
  130.                 return 1;
  131.         }else if (word1->count > word2->count) {
  132.                 return -1;
  133.         }
  134.         return 0;
  135. }

  136. int main(void)
  137. {
  138.         struct word table[MAX_WORD_TYPE];
  139.         char *file;
  140.         int len;
  141.         int table_len;

  142.         file = read_file(FILE_NAME, &len);
  143.         if (file != NULL) {
  144.                 memset(table, 0, sizeof(table));
  145.                 count_word(file, len, table, MAX_WORD_TYPE);
  146.                 table_len = get_table_len(table, MAX_WORD_TYPE);
  147.                 qsort(table, table_len, sizeof(struct word), compare_word);
  148.                 print_word(table, table_len);
  149.                 free(file);
  150.                 return 0;
  151.         }
  152.         return -1;
  153. }
复制代码

论坛徽章:
0
10 [报告]
发表于 2013-09-20 01:30 |只看该作者
很简单,定义一个char型的数组,例如char a[128],注意,必须是128,和ASII表数目对应,然后遇到字母就以它为下表的元素加1,值到全部弄完,然后打印数组元素大小不为0的,就是出现过的,下表是字母,大小是出现次数。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2013-09-18 23:47 |只看该作者
map<string, unsigned long>

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
8 [报告]
发表于 2013-09-18 23:17 |只看该作者
基础题目还是好好上学吧.

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
7 [报告]
发表于 2013-09-18 23:14 |只看该作者
你得先定义下什么叫“单词”,比如“100”算不算“单词”?“C++”算不算“单词”?“AT&T”算几个“单词”?拼错的算不算“单词”?“こんにちは means hello”这句话有几个“单词”?

论坛徽章:
0
6 [报告]
发表于 2013-09-18 21:29 |只看该作者
回复 5# shentar


    太复杂了,看不懂

论坛徽章:
0
5 [报告]
发表于 2013-09-18 10:48 |只看该作者
我正好写过这道题目,不过重点不在排序上面,排序写得很糟糕。

http://shentar.me/%E4%B8%80%E9%8 ... %E6%9E%90%E9%A2%98/

论坛徽章:
0
4 [报告]
发表于 2013-09-18 09:39 |只看该作者
怎么没人啊
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP