LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 793|回复: 1

LZX压缩源代码中碰到的问题(感兴趣的可以进来看看)

[复制链接]
发表于 2007-1-4 18:24:24 | 显示全部楼层 |阅读模式
红色代码的部分在我看来永远不会执行,而且,while(cursor && ((bbp - cursor) <= max_dist))执行一次就会退出循环,如果是这样的话,根本用不着循环结构呀.

由于写代码的人是水平很高的,我想不太可能有这样的错误,所以我断定自己错了,可就不知道错在什么地方.由于源代码很长,如果有什么不理解的可以参看源代码:

http://www.speakeasy.org/~russotto/chm/lzx_compress.tar.gz

只是我的理解:下面的函数选自lz_nonslide.c 功能是分析缓冲区的数据(按byte)让chartable[256]指向缓冲区首次出现的字符的位置,在后面如果再出现这个字符,就让prevtab指向chartable中指向首次出现的位置的指针chartab[char],而且让lentab的相应位置的值为1. 最后统计前后匹配的长度,存入lentab.



  1. static void lz_analyze_block(lz_info *lzi)
  2. {
  3.   int *lentab, *lenp;
  4.   u_char **prevtab, **prevp;
  5.   u_char *bbp, *bbe;
  6.   u_char *chartab[256];
  7.   u_char *cursor;
  8.   int prevlen;
  9.   int ch;
  10.   int maxlen;
  11.   long wasinc;
  12.   int max_dist = lzi->max_dist;




  13.   memset(chartab, 0, sizeof(chartab));
  14.   prevtab = prevp = lzi->prevtab;
  15.   lentab = lenp = lzi->lentab;
  16.   memset(prevtab, 0, sizeof(*prevtab) * lzi->chars_in_buf);
  17.   memset(lentab, 0, sizeof(*prevtab) * lzi->chars_in_buf);

  18.   bbp = lzi->block_buf;
  19.   bbe = bbp + lzi->chars_in_buf;
  20.   while (bbp < bbe) {
  21.     if (chartab[ch = *bbp]) {
  22.       *prevp = chartab[ch];
  23.       *lenp = 1;
  24.     }
  25.     chartab[ch] = bbp;
  26.     bbp++;
  27.     prevp++;
  28.     lenp++;
  29.   }

  30.   wasinc = 1;
  31.   for (maxlen = 1; wasinc && (maxlen < lzi->max_match); maxlen++) {

  32.     bbp = bbe - maxlen - 1;
  33.     lenp = lentab + lzi->chars_in_buf - maxlen - 1;
  34.     prevp = prevtab + lzi->chars_in_buf - maxlen - 1;
  35.     wasinc = 0;
  36.     while (bbp > lzi->block_buf) {
  37.       if (*lenp == maxlen) {

  38.         ch = bbp[maxlen];
  39.         cursor = *prevp;
  40.         while(cursor && ((bbp - cursor) <= max_dist)) {
  41.           prevlen = *(cursor - lzi->block_buf + lentab);
  42.           if (cursor[maxlen] == ch) {
  43.             *prevp = cursor;
  44.             (*lenp)++;
  45.             wasinc++;
  46.             break;
  47.           }
  48.           if (prevlen != maxlen) break;
  49. [color=red] cursor = *(cursor - lzi->block_buf + prevtab);[/color]
  50.         }

  51.       }
  52.       bbp--;
  53.       prevp--;
  54.       lenp--;
  55.     }

  56.   }
  57.   lzi->analysis_valid = 1;

  58. }

复制代码
 楼主| 发表于 2007-1-6 07:55:55 | 显示全部楼层
自已解决了,原来问题在这. chartable原来指向重复出现的最近一次出现的那个字符,而不是第一个.


while (bbp < bbe) {
    if (chartab[ch = *bbp]) {
      *prevp = chartab[ch];
      *lenp = 1;
    }
    chartab[ch] = bbp;
    bbp++;
    prevp++;
    lenp++;
  }
回复 支持 反对

使用道具 举报

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

本版积分规则

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