免费注册 查看新帖 |

Chinaunix

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

[C] 大家好帮我看段代码吧 谢谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-30 21:04 |只看该作者 |倒序浏览
19可用积分
大家好,帮忙看下这段代码主要实现的什么功能,稍微介绍一下这个程序好么,谢谢。小弟混chinaunix不久 只有19积分 全部奉上  再次感谢下大家
typedef struct
{
    unsigned long Signature;
    /* put any other info here like file name and date */
} FileHeader;

typedef byte BufferArray[BufSize + 1];
typedef word CodeType;  /* 0..MaxChar */
typedef byte UpIndex;   /* 0..PredMax */
typedef word DownIndex; /* 0..TwiceMax */
typedef DownIndex TreeDownArray[PredMax + 1];  /* UpIndex */
typedef UpIndex TreeUpArray[TwiceMax + 1];     /* DownIndex */

BufferArray InBuffer;           /* input file buffer */
BufferArray OutBuffer;          /* output file buffer */
char InName[80];                /* input file name */
char OutName[80];               /* output file name */
char CompStr[4];                /* response from Expand? prompt */
FILE *InF;                      /* input file */
FILE *OutF;                     /* output file */

TreeDownArray Left, Right;      /* child branches of code tree */
TreeUpArray Up;                 /* Parent branches of code tree */
bool CompressFlag;              /* true to compress file */
byte BitPos;                    /* current bit in byte */
CodeType InByte;                /* current input byte */
CodeType OutByte;               /* current output byte */
word InSize;                    /* current chars in input buffer */
word OutSize;                   /* Current chars in output buffer */
word Index;                     /* general purpose index */

char *Usage = {"Usage: splay [x] infile outfile\n\n"
               "Where 'x' denotes expand infile to outfile\n"
               "Normally compress infile to outfile\n"
};

/* function prototypes */
void InitializeSplay(void);
void Splay(CodeType Plain);
void FlushOutBuffer(void);
void WriteByte(void);
void Compress(CodeType Plain);
void ReadHeader(void);
byte GetByte(void);
CodeType Expand(void);
void ExpandFile(void);

/* initialize the splay tree - as a balanced tree */
void InitializeSplay(void)
{
    DownIndex I;
    int /*UpIndex*/ J;
    DownIndex K;
   
    for (I = 1; I <= TwiceMax; I++)
        Up[I] = (I - 1) >> 1;
    for (J = 0; J <= PredMax; J++)
    {
        K = ((byte)J + 1) << 1;
        Left[J] = K - 1;
        Right[J] = K;
    }
}

/* rearrange the splay tree for each succeeding character */
void Splay(CodeType Plain)
{
    DownIndex A, B;
    UpIndex C, D;
   
    A = Plain + MaxChar;
   
    do
    {
        /* walk up the tree semi-rotating pairs */
        C = Up[A];
        if (C != Root)
        {
            /* a pair remains */
            D = Up[C];
            
            /* exchange children of pair */
            B = Left[D];
            if (C == B)
            {
                B = Right[D];
                Right[D] = A;
            }
            else
                Left[D] = A;
            
            if (A == Left[C])
                Left[C] = B;
            else
                Right[C] = B;
            
            Up[A] = D;
            Up[B] = C;
            A = D;
        }
        else
            A = C;
    } while (A != Root);
}

/* flush output buffer and reset */
void FlushOutBuffer(void)
{
    if (OutSize > 0)
    {
        fwrite(OutBuffer+1, sizeof(byte), OutSize, OutF);
        OutSize = 0;
    }
}

/* output byte in OutByte */
void WriteByte(void)
{
    if (OutSize == BufSize)
        FlushOutBuffer();
    OutSize++;
    OutBuffer[OutSize] = OutByte;
}


/* compress a single char */
void Compress(CodeType Plain)
{
    DownIndex A;
    UpIndex U;
    word Sp;
    bool Stack[PredMax+1];
   
    A = Plain + MaxChar;
    Sp = 0;
   
    /* walk up the tree pushing bits onto stack */
    do
    {
        U = Up[A];
        Stack[Sp] = (Right[U] == A);
        Sp++;
        A = U;
    } while (A != Root);
   
    /* unstack to transmit bits in correct order */
    do
    {
        Sp--;
        if (Stack[Sp])
            OutByte |= BitMask[BitPos];
        if (BitPos == 7)
        {
            /* byte filled with bits, write it out */
            WriteByte();
            BitPos = 0;
            OutByte = 0;
        }
        else
            BitPos++;
    } while (Sp != 0);
   
    /* update the tree */
    Splay(Plain);
}

/* compress input file, writing to outfile */
void CompressFile(void)
{
    FileHeader Header;
   
    /* write header to output */
    Header.Signature = Sig;
    fwrite(&Header, sizeof(FileHeader), 1, OutF);
   
    /* compress file */
    OutSize = 0;
    BitPos = 0;
    OutByte = 0;
    do
    {
        InSize = fread(InBuffer+1, sizeof(byte), BufSize, InF);
        for (Index = 1; Index <= InSize; Index++)
            Compress(InBuffer[Index]);
    } while (InSize >= BufSize);
   
    /* Mark end of file */
    Compress(EofChar);
   
    /* Flush buffers */
    if (BitPos != 0)
        WriteByte();
    FlushOutBuffer();
}

/* read a compressed file header */
void ReadHeader(void)
{
    FileHeader Header;
   
    fread(&Header, sizeof(FileHeader), 1, InF);
    if (Header.Signature != Sig)
    {
        printf("Unrecognized file format!\n");
        exit(1);
    }
}

/* return next byte from compressed input */
byte GetByte(void)
{
    Index++;
    if (Index > InSize)
    {
        /* reload file buffer */
        InSize = fread(InBuffer+1, sizeof(byte), BufSize, InF);
        Index = 1;
        /* end of file handled by special marker in compressed file */
    }
   
    /* get next byte from buffer */
    return InBuffer[Index];
}

/* return next char from compressed input */
CodeType Expand(void)
{
    DownIndex A;
   
    /* scan the tree to a leaf, which determines the character */
    A = Root;
    do
    {
        if (BitPos == 7)
        {
            /* used up bits in current byte, get another */
            InByte = GetByte();
            BitPos = 0;
        }
        else
            BitPos++;
        
        if ((InByte & BitMask[BitPos]) == 0)
            A = Left[A];
        else
            A = Right[A];
    } while (A <= PredMax);
   
    /* Update the code tree */
    A -= MaxChar;
    Splay(A);
   
    /* return the character */
    return A;
}

/* uncompress the file and write output */
void ExpandFile(void)
{
    /* force buffer load first time */
    Index = 0;
    InSize = 0;
    /* nothing in output buffer */
    OutSize = 0;
    /* force bit buffer load first time */
    BitPos = 7;
   
    /* read and expand the compressed input */
    OutByte = Expand();
    while (OutByte != EofChar)
    {
        WriteByte();
        OutByte = Expand();
    }
   
    /* flush the output buffer */
    FlushOutBuffer();
}

int main(int argc, char *argv[])
{

    if (argc < 3)
    {
        printf(Usage);
        exit(1);
    }
   
    if (argc == 4 && (strlen(argv[1]) == 1) && toupper(argv[1][0]) == 'X')
    {
        strcpy(InName, argv[2]);
        strcpy(OutName, argv[3]);
        CompressFlag = false;
    }
    else
    {
        if (argc == 4)
        {
            printf(Usage);
            exit(1);
        }
        CompressFlag = true;
        strcpy(InName, argv[1]);
        strcpy(OutName, argv[2]);
    }
        
    InitializeSplay();
   
    if ((InF = fopen(InName, "rb")) == NULL)
    {
        printf("Unable to open input file: %s\n", InName);
        exit(1);
    }
    if ((OutF = fopen(OutName, "wb")) == NULL)
    {
        printf("Unable to open output file: %s\n", OutName);
        exit(1);
    }
   
    if (CompressFlag)
        CompressFile();
    else
    {
        ReadHeader();
        ExpandFile();
    }
   
    fclose(InF);
    fclose(OutF);
   
    return 0;
}

最佳答案

查看完整内容

应该是霍夫曼压缩 解压缩文件.InitializeSplay //构建一个完全二叉树, 二叉树元素按顺序排列, 每个元素可理解为代表一个字符0x00~0xff......Splay //将被访问的字符上浮, 以便访问频率高的字符可以占据较小的权重, 即能用较少的bits表示Compress //将字符位于树中的节点位置到树根的路径表示成二进制位, 如果累积到达8位(一个字节)则记录下该字节

论坛徽章:
0
2 [报告]
发表于 2009-05-30 21:04 |只看该作者
应该是霍夫曼压缩 解压缩文件.

InitializeSplay //构建一个完全二叉树, 二叉树元素按顺序排列, 每个元素可理解为代表一个字符0x00~0xff......

Splay //将被访问的字符上浮, 以便访问频率高的字符可以占据较小的权重, 即能用较少的bits表示

Compress //将字符位于树中的节点位置到树根的路径表示成二进制位, 如果累积到达8位(一个字节)则记录下该字节

论坛徽章:
0
3 [报告]
发表于 2009-05-30 22:05 |只看该作者
看起来像是压缩和解压缩的代码

论坛徽章:
0
4 [报告]
发表于 2009-05-30 23:15 |只看该作者
嗯。应该就是压缩和解压缩的代码。比较清晰。

CompressFile(); 压缩
ExpandFile();     解压缩

通过分析参数,置flag,来判断是压缩还是解压缩。

当然了,具体的逻辑比我说的复杂多了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP