鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: qpwoeiruyt

[已解决]哈夫曼码结构体的疑问

[复制链接]
 楼主| 发表于 2019-2-20 01:29:51 | 显示全部楼层
人造人 发表于 2019-2-19 18:19
我还是没有问到我需要的内容,我举个例子

下面这个程序

a:001
b:01
c:1

这样子啊  但上面的001 01 1是我随便写的 正确的要写完huffman code才能显示出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 01:49:27 | 显示全部楼层

嗯,要的就是这个
我需要研究研究
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 02:11:10 | 显示全部楼层
我看懂这个代码了,但是我没办法做到只是修改huffman_code函数
我可以随意修改这个代码,是吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-20 02:23:08 | 显示全部楼层
人造人 发表于 2019-2-19 19:11
我看懂这个代码了,但是我没办法做到只是修改huffman_code函数
我可以随意修改这个代码,是吧?

可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 03:30:26 | 显示全部楼层
这棵树已经创建好了,时间不早了,先睡了,睡醒以后再想如何得到你想要的输出

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define DATA_SIZE 256

  5. typedef struct noeud_tag
  6. {
  7.         char ch;
  8.         size_t freq;
  9.         struct noeud_tag *fils_g;        // 左枝点
  10.         struct noeud_tag *fils_d;        // 右枝点
  11. } noeud_t;

  12. // 能不改的函数尽量不改
  13. void frequence(int *freq, char *chaine)                // 此函数是为了找出字符串里每个ASCII字符的频率
  14. {
  15.         char car;
  16.         int i;
  17.         int length;

  18.         // 计算字符串的长度
  19.         length = strlen(chaine);

  20.         //建立一个表格 现在频率全是0
  21.         for(i = 0; i < 256; i++)
  22.         {
  23.                 freq[i] = 0;
  24.         }

  25.         // 计算字符串里每个字母的频率
  26.         for(i = 0; i < length; i++)
  27.         {
  28.                 car = chaine[i];
  29.                 freq[car]++;
  30.         }

  31.         return;
  32. }

  33. // 重写此函数
  34. size_t init_tab_noeud(noeud_t *data, int *freq)
  35. {
  36.         size_t index = 0;
  37.         for(size_t i = 0; i < DATA_SIZE; ++i)
  38.         {
  39.                 if(freq[i] > 0)
  40.                 {
  41.                         memset(&data[index], 0, sizeof(data[index]));
  42.                         data[index].ch = (char)i;
  43.                         data[index].freq = freq[i];
  44.                         ++index;
  45.                 }
  46.         }

  47.         return index;
  48. }

  49. // 按频率从小到大排序
  50. void sort(noeud_t *data, size_t length)
  51. {
  52.         for(size_t i = 0; i < length; ++i)
  53.         {
  54.                 for(size_t j = i + 1; j < length; ++j)
  55.                 {
  56.                         if(data[i].freq > data[j].freq)
  57.                         {
  58.                                 noeud_t tmp = data[i];
  59.                                 data[i] = data[j];
  60.                                 data[j] = tmp;
  61.                         }
  62.                 }
  63.         }
  64. }

  65. noeud_t *huffman_code(noeud_t *data, size_t length)
  66. {
  67.         size_t index = DATA_SIZE;        // 指向最后一个可用位置
  68.         while(length != 1)
  69.         {
  70.                 sort(data, length);

  71.                 data[--index] = data[0];
  72.                 data[--index] = data[1];

  73.                 memset(&data[0], 0, sizeof(data[0]));
  74.                 data[0].fils_g = &data[index + 1];
  75.                 data[0].fils_d = &data[index];
  76.                 data[0].freq = data[0].fils_g->freq + data[0].fils_d->freq;

  77.                 for(size_t i = 1; i < length - 1; ++i)
  78.                         data[i] = data[i + 1];
  79.                 --length;
  80.         }
  81.         return &data[0];
  82. }

  83. void preorder_traversal(noeud_t *root)
  84. {
  85.         if(root)
  86.         {
  87.                 printf("\nch:\t\'%c\'\n", root->ch);
  88.                 printf("pre:\t%u\n", root->freq);
  89.                 preorder_traversal(root->fils_g);
  90.                 preorder_traversal(root->fils_d);
  91.         }
  92. }

  93. // 尽量保证和原来一样,这里也使用数组
  94. // 说真的,数组很不好用
  95. // 为了和原来尽量一样,不得不用
  96. int main(void)
  97. {
  98.         char *chaine = "aaababaaababbbbbbbbbbbbabcddddbcaaabbbbbbbbbbbabbaa";
  99.         int freq[256];
  100.         size_t length;
  101.         noeud_t data[DATA_SIZE];
  102.         noeud_t *racine;

  103.         frequence(freq, chaine);
  104.         length = init_tab_noeud(data, freq);
  105.         racine = huffman_code(data, length);
  106.         preorder_traversal(data);

  107.         return(EXIT_SUCCESS);
  108. }
复制代码


  1. ch:     ' '
  2. pre:    51

  3. ch:     ' '
  4. pre:    21

  5. ch:     ' '
  6. pre:    6

  7. ch:     'c'
  8. pre:    2

  9. ch:     'd'
  10. pre:    4

  11. ch:     'a'
  12. pre:    15

  13. ch:     'b'
  14. pre:    30
  15. 请按任意键继续. . .
复制代码


1.png

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
行客 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-20 14:10:23 | 显示全部楼层
人造人 发表于 2019-2-19 20:30
这棵树已经创建好了,时间不早了,先睡了,睡醒以后再想如何得到你想要的输出

大佬辛苦了   早点休息
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 16:51:12 | 显示全部楼层    本楼为最佳答案   
好了

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define DATA_SIZE        256
  5. #define CODE_TABLE_SIZE        256

  6. typedef struct noeud_tag
  7. {
  8.         char ch;
  9.         size_t freq;
  10.         struct noeud_tag *fils_g;        // 左枝点
  11.         struct noeud_tag *fils_d;        // 右枝点
  12. } noeud_t;

  13. typedef struct
  14. {
  15.         char code[100];
  16. } code_item_t;

  17. // 能不改的函数尽量不改
  18. void frequence(int *freq, char *chaine)                // 此函数是为了找出字符串里每个ASCII字符的频率
  19. {
  20.         char car;
  21.         int i;
  22.         int length;

  23.         // 计算字符串的长度
  24.         length = strlen(chaine);

  25.         //建立一个表格 现在频率全是0
  26.         for(i = 0; i < 256; i++)
  27.         {
  28.                 freq[i] = 0;
  29.         }

  30.         // 计算字符串里每个字母的频率
  31.         for(i = 0; i < length; i++)
  32.         {
  33.                 car = chaine[i];
  34.                 freq[car]++;
  35.         }

  36.         return;
  37. }

  38. // 重写此函数
  39. size_t init_noeud(noeud_t *data, int *freq)
  40. {
  41.         size_t index = 0;
  42.         for(size_t i = 0; i < DATA_SIZE; ++i)
  43.         {
  44.                 if(freq[i] > 0)
  45.                 {
  46.                         memset(&data[index], 0, sizeof(data[index]));
  47.                         data[index].ch = (char)i;
  48.                         data[index].freq = freq[i];
  49.                         ++index;
  50.                 }
  51.         }

  52.         return index;
  53. }

  54. // 按频率从小到大排序
  55. void sort(noeud_t *data, size_t length)
  56. {
  57.         for(size_t i = 0; i < length; ++i)
  58.         {
  59.                 for(size_t j = i + 1; j < length; ++j)
  60.                 {
  61.                         if(data[i].freq > data[j].freq)
  62.                         {
  63.                                 noeud_t tmp = data[i];
  64.                                 data[i] = data[j];
  65.                                 data[j] = tmp;
  66.                         }
  67.                 }
  68.         }
  69. }

  70. noeud_t *huffman_tree(noeud_t *data, size_t length)
  71. {
  72.         size_t index = DATA_SIZE;        // 指向最后一个可用位置
  73.         while(length != 1)
  74.         {
  75.                 sort(data, length);

  76.                 data[--index] = data[0];
  77.                 data[--index] = data[1];

  78.                 memset(&data[0], 0, sizeof(data[0]));
  79.                 data[0].fils_g = &data[index + 1];
  80.                 data[0].fils_d = &data[index];
  81.                 data[0].freq = data[0].fils_g->freq + data[0].fils_d->freq;

  82.                 for(size_t i = 1; i < length - 1; ++i)
  83.                         data[i] = data[i + 1];
  84.                 --length;
  85.         }
  86.         return &data[0];
  87. }

  88. void preorder_traversal(noeud_t *root)
  89. {
  90.         if(root)
  91.         {
  92.                 printf("\nch:\t\'%c\'\n", root->ch);
  93.                 printf("pre:\t%u\n", root->freq);
  94.                 preorder_traversal(root->fils_g);
  95.                 preorder_traversal(root->fils_d);
  96.         }
  97. }

  98. void traverse_tree(noeud_t *root, code_item_t *code_table, char code[1024], size_t index)
  99. {
  100.         if(!root->fils_g && !root->fils_d)
  101.         {
  102.                 code[index] = '\0';
  103.                 strcpy(code_table[root->ch].code, code);
  104.         }
  105.         if(root->fils_g)
  106.         {
  107.                 code[index] = '0';
  108.                 traverse_tree(root->fils_g, code_table, code, index + 1);
  109.         }
  110.         if(root->fils_d)
  111.         {
  112.                 code[index] = '1';
  113.                 traverse_tree(root->fils_d, code_table, code, index + 1);
  114.         }
  115. }

  116. void init_code_table(code_item_t *code_table, noeud_t *code_tree)
  117. {
  118.         char code[1024];
  119.         size_t index = 0;
  120.         memset(code_table, 0, sizeof(code_item_t) * CODE_TABLE_SIZE);
  121.         traverse_tree(code_tree, code_table, code, index);
  122. }

  123. // 尽量保证和原来一样,这里也使用数组
  124. // 说真的,数组很不好用
  125. // 为了和原来尽量一样,不得不用
  126. int main(void)
  127. {
  128.         char *chaine = "aaababaaababbbbbbbbbbbbabcddddbcaaabbbbbbbbbbbabbaa";
  129.         int freq[256];
  130.         size_t length;
  131.         noeud_t data[DATA_SIZE];
  132.         noeud_t *code_tree;
  133.         code_item_t code_table[CODE_TABLE_SIZE];

  134.         frequence(freq, chaine);
  135.         length = init_noeud(data, freq);
  136.         code_tree = huffman_tree(data, length);
  137.         init_code_table(code_table, code_tree);

  138.         printf("a: %s\n", code_table['a'].code);
  139.         printf("b: %s\n", code_table['b'].code);
  140.         printf("c: %s\n", code_table['c'].code);
  141.         printf("d: %s\n", code_table['d'].code);

  142.         preorder_traversal(code_tree);
  143.         return(EXIT_SUCCESS);
  144. }
复制代码

  1. a: 01
  2. b: 1
  3. c: 000
  4. d: 001

  5. ch:     ' '
  6. pre:    51

  7. ch:     ' '
  8. pre:    21

  9. ch:     ' '
  10. pre:    6

  11. ch:     'c'
  12. pre:    2

  13. ch:     'd'
  14. pre:    4

  15. ch:     'a'
  16. pre:    15

  17. ch:     'b'
  18. pre:    30
  19. 请按任意键继续. . .
复制代码


1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-20 19:54:35 | 显示全部楼层

谢谢啦  问一下最后那个图是怎样打印出来的?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 20:04:58 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-20 19:54
谢谢啦  问一下最后那个图是怎样打印出来的?

用PPT自己画的
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-20 20:05:35 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-20 19:54
谢谢啦  问一下最后那个图是怎样打印出来的?

演示文稿1.zip (28.45 KB, 下载次数: 1)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-21 14:37:26 | 显示全部楼层

谢谢啦   大神的code能不能写点注释进去  有一些你写的东西不是太清楚 就是每个函数前头简单解释一下我就会了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-21 14:42:53 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-21 14:37
谢谢啦   大神的code能不能写点注释进去  有一些你写的东西不是太清楚 就是每个函数前头简单解释一下我就 ...

哪个函数看不懂?
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-22 00:15:21 | 显示全部楼层
人造人 发表于 2019-2-21 07:42
哪个函数看不懂?
^_^

大致都懂了

现在又来了个新问题

大佬会用flex编写词法分析器吗?写了个逆波兰表达式的c文件 如何将它写成flex呢? 里面的结构看上去挺相近的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-22 00:38:55 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-22 00:15
大致都懂了

现在又来了个新问题

加我qq:1440332527
我没试过,不过可以研究研究
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-2-22 00:40:21 | 显示全部楼层
人造人 发表于 2019-2-21 17:38
加我qq:1440332527
我没试过,不过可以研究研究
^_^

大佬有微信吗?qq忘了密码 现在一直用微信
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-22 00:41:33 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-22 00:40
大佬有微信吗?qq忘了密码 现在一直用微信

没有微信,我一直用qq
我的微信密码忘了
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-2-22 00:45:25 | 显示全部楼层
qpwoeiruyt 发表于 2019-2-22 00:15
大致都懂了

现在又来了个新问题

那就在这里说吧
详细描述一下这个问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 12:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表