13.压缩文本

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

原始文本文件中的非字母的字符,直接拷贝到压缩文件中;
原始文件中的词(全部由字母组成),如果是第一次出现,则将该词加入到一个词的列表中,并拷贝到压缩文件中;否则该词不拷贝到压缩文件中,而是将该词在词的列表中的位置拷贝到压缩文件中;
词的列表的起始位置为 1。
词的定义为文本中由大小写字母组成的最大连续序列。(单词不跨行)大写字母和小写字母认为是不同的字母,即 abc 和 Abc 是不同的词。例子如下:

x-ray 包括两个词 x 和 ray
mary’s 包括两个词 mary 和 s
a c-Dec 包括三个词 a 和 c 和 Dec
请编写一个程序,实现文本的压缩。

输入

输入为一段文本,你可以假设输入中不会出现数字,词的数量不会超过 1’000’000,并且输入文本的大小不超过 10M。

输出

输出压缩后的文本。

测试用例
in:
Please, please do it–it would please Mary very,
very much.

Thanks
out:
Please, please do it–4 would 2 Mary very,
7 much.

Thanks

大一做过这题,然而数据量没那么变态,直接把单词存在二维数组并在前面标号。如果新的单词和之前表里面的单词重复则输出标号,否则原样输出。然而这样会re,因为我们开不了那么大的数组,后面经大佬的指点,自学了hash表拉链法解决冲突才过的。

扫描二维码关注公众号,回复: 3749549 查看本文章
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<ctype.h>
#define MAX 60013
const int mod1=60013;
const int mult1=1013;
const long mod2=1000000007;
const long mult2=1000007;

typedef struct node
{
    int val1;
    int val2;
    struct node *next;
}HashTable;

char ch,s[100];
int repeat;
int flag,k;
HashTable *Hash[MAX],*vis;

int FirstHash(char s[]);
int SecondHash(char s[]);
void insert(HashTable **Hash,int repeat,char s[]);
int find(HashTable **Hash,int repeat[],char s[]);

int main()
{
	int j=1;
	for(int i=0;i<mod1;i++)
		Hash[i]=NULL;
    while(~(ch=getchar()))
	{
        if(!isalpha(ch))
		{
            if(!flag)
            {
                s[k]='\0';
                repeat=0;
                if(find(Hash,&repeat,s))
					printf("%d",repeat);
                else
                {
                    insert(Hash,j++,s);
                    printf("%s",s);
                }
				putchar(ch);
                flag=1;
                k=0;
            }
            else
			{
				putchar(ch);
                flag=1;
            }
        }
        else
        {
            flag=0;
            s[k++]=ch;
        }
    }
}

int FirstHash(char s[])
{
    int ans=0;
    for(int i=0;i<strlen(s);i++)
        ans=(ans*mult1+s[i]-'A'+1)%mod1;
    return ans;
}
int SecondHash(char s[])
{
    int ans=0;
    for(int i=0;i<strlen(s);i++)
        ans=(ans*mult2+s[i]-'A'+1)%mod2;
    return ans;
}
void insert(HashTable **Hash,int repeat,char s[])
{
    int key=FirstHash(s);
    HashTable *q=(HashTable*)malloc(sizeof(HashTable));
    q->val1=repeat;
    q->next=NULL;
    q->val2=SecondHash(s);
    if(Hash[key]!=NULL)
		vis->next=q;
    else
		Hash[key]=q;
}
int find(HashTable **Hash,int repeat[],char s[])
{
    int key2=FirstHash(s);
    HashTable *p=Hash[key2];
    int val2=SecondHash(s);
    if(p==NULL)
        return 0;
    while(p->next!=NULL)
	{
        if(p->val2==val2)
		{
            *repeat=p->val1;
            return 1;
        }
        p=p->next;
    }
    if(p->val2==val2)
	{
        *repeat=p->val1;
        return 1;
    }
    vis=p;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ArgentumHook/article/details/83054637
今日推荐