c语言压缩文本文件 求解答

c语言压缩文本文件 求解答,第1张

#include "stdio.h"

#include "string.h"

#include "malloc.h"

#define MOD_ADLER         65521

#define HASHMAX           1000

#define MAX_INT           9999999 // 最大读取数字为99999999

#define CHARBUFLEN        40960

#define DECOMPRESSINITLEN 1024

struct stringInfo

{

int No                     // 字符串出现的次序

char * str                 // 字符串

struct stringInfo * next   // 下一节点

} * strTable[HASHMAX] // 用于压缩

int isCompress

char ** strTableDe // 解压缩表,用于解压缩

long  deTableLen    // 解压缩表长度

long  curStrNum     // 目前的字符串数量

// 程序初始化

void init()

{

int i

curStrNum = 1

isCompress = 1 // 压缩模式,等于0时解压缩

if(isCompress)

{

for(i=0 i<HASHMAX i++) strTable[i] = NULL

deTableLen = 0

strTableDe = NULL

}

else

{

deTableLen = DECOMPRESSINITLEN

strTableDe = (char **)malloc(deTableLen * sizeof(char *))

for(i=0 i<deTableLen i++) strTableDe[i] = NULL

}

}

// 重新申请内存

void ReMallocDeTable()

{

deTableLen <<= 1

strTableDe = (char **)realloc(strTableDe, deTableLen * sizeof(char *))

}

// 程序结束,释放内存

void over()

{

int i

struct stringInfo *pNext, *pDel

for(i=0 i<HASHMAX i++)

{

pNext = strTable[i]

while(pNext)

{

free(pNext->str)

pDel  = pNext

pNext = pNext->next

free(pDel)

}

}

if(strTableDe)

{

for(i=0 i<curStrNum i++) 

{

//printf("%d\t%s\n", i, strTableDe[i])

free(strTableDe[i])

}

free(strTableDe)

}

}

// adler32 校验和算法

unsigned long adler32(unsigned char * data, size_t len)

{

    unsigned long a = 1, b = 0

size_t index

 

    for (index = 0 index < len ++index)

    {

        a = (a + data[index]) % MOD_ADLER

        b = (b + a) % MOD_ADLER

    }

    return (b << 16) | a

}

// 求字符串的Hash,实现快速查找, 这里用的是adler32算法,可以使用其它任何hash方法

unsigned long Hash(const char * str)

{

return adler32((unsigned char*)str, strlen(str)) % HASHMAX

}

// 复制新字符串

char * copyNewStr(const char * str)

{

char * r = (char *)malloc(strlen(str) + 1)

strcpy(r, str)

return r

}

// 取得字符串出现的次序

int getStrPos(const char * str)

{

unsigned long hash

struct stringInfo * pFirst, * pNext, * pNew

hash  = Hash(str)

pNext = pFirst = strTable[hash]

while(pNext)

{

if(strcmp(pNext->str, str) == 0) return pNext->No

pNext = pNext->next

}

// 没有找到匹配的字符串

pNew = (struct stringInfo *)malloc(sizeof(struct stringInfo))

pNew->next = NULL

pNew->No   = curStrNum++

pNew->str  = copyNewStr(str)

if(pFirst == NULL) strTable[hash] = pNew

else

{

pNext = pFirst

while(pNext->next) pNext = pNext->next

pNext->next = pNew

}

return -1

}

// 读取字符串, 字符串以空格为结束符

// 返回负数的绝对值是读取的是字符串长度,正数为读取的数字

int ReadStr(char * out, const char * in)

{

char *po, *pn

const char *pi

int r

po = out

pi = in

while(('a' <= *pi && *pi <= 'z') || ('A' <= *pi && *pi <= 'Z') || ('0' <= *pi && *pi <= '9'))

*po++ = *pi++ // 只复制大小写字母和数字

*po = 0

// 试着转化为纯数字

r = 0

pn = out

while('0' <= *pn && *pn <= '9') 

{

if(r > MAX_INT) break

r *= 10

r += *pn++ - '0'

}

if(*pn) return out - po // 未成功转化为数字

else return (r & 0x7FFFFFF) | (((po - out) & 0xF) << 27)

}

void main()

{

char readFileBuf[CHARBUFLEN], readStrBuf[CHARBUFLEN]

char *prfb

int num

FILE *fpr, *fpw

fpr = fopen("source.txt", "r") // 输入文件

fpw = fopen("object.txt", "w") // 输出文件

if(fpr == NULL || fpw == NULL) return 

init()

while(!feof(fpr))

{

if(fgets(readFileBuf, CHARBUFLEN-1, fpr)==NULL) break

prfb = readFileBuf

while(*prfb)

{

num = ReadStr(readStrBuf, prfb)

if(num == 0) fputc(*prfb++, fpw) // 没有读取成功

else if(num > 0) // 读入数字

{

prfb += (num >> 27) & 0xF // 移动读取的位数

if(isCompress) fprintf(fpw, "0 %d", num & 0x7FFFFFF) // 压缩模式写入数字,前面添加个数字0

else

{

num &= 0x7FFFFFF

if(num == 0) // 如果读到数字0

{

prfb += 1

num = ReadStr(readStrBuf, prfb) // 读取下一格数据串

if(num > 0)

{

prfb += (num >> 27) & 0xF // 移动读取的位数

fprintf(fpw, "%d", num & 0x7FFFFFF)

}

else fprintf(fpw, "0 ", num & 0x7FFFFFF) // 下一个不是数字

}

else if(num < curStrNum) fprintf(fpw, "%s", strTableDe[num]) // 解压模式写入字符串

else

{

printf("Error : %d, %d\n", num, curStrNum)

fprintf(fpw, "%d", num) // num大于已知的字符串数量,写入数字

}

}

}

else

{

num   = -num

prfb += num // 移动读取的位数

if(isCompress)

{

num = getStrPos(readStrBuf)

if(num < 0) fprintf(fpw, "%s", readStrBuf) // 未出现过的字符串

else fprintf(fpw, "%d", num) // 写入位置

}

else

{

fprintf(fpw, "%s", readStrBuf)

if(curStrNum >= deTableLen) ReMallocDeTable() // 解压表长度不够,重新申请空间

strTableDe[curStrNum++] = copyNewStr(readStrBuf) // 加入解压表

}

}

}

}

if(isCompress) printf("Compress successful!\n")

else printf("Decompress Successful!\n")

over()

}

压缩是一种有效的减小数据量的方法,目前已经被广泛应用于各种类型的信息系统之中。

   一种压缩文本文件的方法如下:

   1. 原始文本文件中的非字母的字符,直接拷贝到压缩文件中;

   2.

原始文件中的词(全部由字母组成),如果是第一次出现,则将该词加入到一个词的列表中,并拷贝到压缩文件中;否则该词不拷贝到压缩文件中,而是将该词在词的列表中的位置拷贝到压缩文件中。

   3. 词的列表的起始位置为 1 。 词的定义为文本中由大小写字母组成的最大序列。大写字母和小写字母认为是不同的字母,即 abc 和 Abc

是不同的词。词的例子如下: * x-ray 包括两个词 x 和 ray * mary's 包括两个词 mary 和 s * a c-Dec 包括三个词 a 和

c 和 Dec 编写一个程序,输入为一组字符串,输出为压缩后的文本。

输入:

   输入为一段文本,你可以假设输入中不会出现数字、每行的长度不会超过 80 个字符,并且输入文本的大小不会超过 10M。

输出:

压缩后的文本。

输入:

Please, please do it--it would please Mary very,

very much.

Thanks

输出:

Please, please do it--4 would 2 Mary very,

7 much.

Thanks

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#define LEN 1<<20

int isArabic(char c){

    return ('a'<=c&&c<='z') || ('A'<=c&&c<='Z')

}

int main()

{

    char dict[LEN]

    char *index[100000]

    char buf[82]

    int nWord=0

    int i,j

    char c

    char *inFile="G:\\in.txt",*outFile="G:\\out.txt"

    FILE *inp,*outp

     

    if((inp=fopen(inFile,"r"))==NULL){

      printf("cannot open\n")

      exit(1)

    }

    if((outp=fopen(outFile,"w"))==NULL){

      printf("out fail\n")

    }

    index[0]=dict

    do{

        /* get a word */

        i=0

        do{

            c=fgetc(inp)

            buf[i++]=c 

        }while(isArabic(c))

         

        buf[i-1]=0

        /* put it to dict */

        if(i>1){

            for(j=0j<nWordj++){

              if(strcmp(index[j],buf)==0){

                break

              }

            }

            if(j==nWord){

              strcpy(index[nWord],buf)

              index[nWord+1]=index[nWord]+strlen(buf)+1

              nWord++

/*              printf("new: %s\n",buf)*/

            }else{

              sprintf(buf,"%d",j+1)

/*              printf("found: %s\n",buf)*/

            }

        }

        /* put it to output file */

        if(c!=EOF)

          fprintf(outp,"%s%c",buf,c)

        else

          fprintf(outp,"%s",buf)

    }while(c!=EOF)

     

    fclose(inp)

    fclose(outp)

/*    system("PAUSE")*/

    return EXIT_SUCCESS

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/11870602.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存