最近一直在研究百度之星的题目。刚好碰到初赛第三题,查阅了网上各牛人的解题方法,感觉收获颇多,对其中的hash的方法自己也有所理解,因此顺着自己的思路,也完成了基于hash表的该题的解法。与大家一同分享
第三题(共四题 100 分):字符串替换( 30 分)
题目描述:请编写程序,根据指定的对应关系,把一个文本中的字符串替换成另外的字符串。
输入数据:程序读入已被命名为 text.txt 和 dict.txt 的两个输入数据文本文件, text.txt 为一个包含大量字符串(含中文)的文本,以 whitespace 为分隔符; dict.txt 为表示字符串( s1 )与字符串( s2 )的对应关系的另一个文本(含中文),大约在 1 万行左右,每行两个字符串(即 s1 和 s2 ),用一个 \t 或空格分隔。 dict.txt 中各行的 s1 没有排序,并有可能有重复,这时以最后出现的那次 s1 所对应的 s2 为准。 text.txt 和 dict.txt 中的每个字符串都可能包含除 whitespace 之外的任何字符。 text.txt 中的字符串必须和 dict.txt 中的某 s1 完全匹配才能被替换。(为便于调试,您可下载测试 text.txt 和 dict.txt 文件,实际运行时我们会使用不同内容的输入文件。)
输出数据:在标准输出上打印 text.txt 被 dict.txt 替换后了的整个文本。
评分标准:程序输出结果必须正确,内存使用越少越好,程序的执行时间越快越好。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH_SIZE 20000
#define MAX_LINE_SIZE 128*1024
struct ThashPoint
{
char *s1; //dict.txt 第一个字符串
char *s2; //dict.txt 第二个字符串
struct ThashPoint *next; //根据相应的hash值确定hash链表
};
struct ThashPoint *Hash[MAX_HASH_SIZE];//建立hash表
char line[MAX_LINE_SIZE];
char lines[MAX_LINE_SIZE];
FILE *f;
char *s1; //用于读取dict.txt 中第一个字符串
char *s2; //用于读取dict.txt 中第二个字符串
int read_line(void)
{
int i = 0;
fgets(lines,MAX_LINE_SIZE,f) ;
if(strlen(lines)>0&&lines[strlen(lines)-1]=='\n')
lines[strlen(lines)-1]= '\0';
if(strlen(lines)<3)
return 0;
#if 1
for(i = 0;lines[i]!= '\0';i++ )
{
if(lines[i] == ' '||lines[i]== '\t')
{
s1 = lines;
s2 = lines+i+1;
lines[i] = '\0';
return 1;
}
}
#endif
return 0;
}
int hash_count(char *s)
{
int address = sizeof(s)%MAX_HASH_SIZE;
int i=0;
for(i=0;s[i];i++)
address = (address*100*s[i]+128)%MAX_HASH_SIZE;
return address;
}
void insert_hash_table(void)
{
int address = hash_count(s1);
struct ThashPoint *p;
for(p = Hash[address];p;p=p->next)
{
if(strcmp(p->s1,s1)==0)
{
p->s2= (char *) malloc(sizeof(char)*(strlen(s2)+1));
strcpy(p->s2,s2);
}
}
p = (ThashPoint *)malloc(sizeof(ThashPoint));
p->s1 = (char *)malloc(sizeof(char)*(strlen(s1)+1));
strcpy(p->s1,s1);
p->s2 = (char *)malloc(sizeof(char)*(strlen(s2)+1));
strcpy(p->s2,s2);
p->next = Hash[address];
Hash[address] = p;
}
void init_hash_fuc(void)
{
f = fopen("dict.txt","r");
while(read_line())
{
insert_hash_table();
}
fclose(f);
}
void Print(char *s)
{
int address;
struct ThashPoint *p;
address = hash_count(s);
for(p=Hash[address];p;p=p->next)
{
if(!strcmp(p->s1,s))
{
printf("%s",p->s2);
return;
}
}
printf("%s",s);
}
int main()
{
init_hash_fuc();//初始化hash表 主要是读取dict.txt文件
FILE *fp;
fp = fopen("test.txt","r");
char c;
int i=0;
while((c = fgetc(fp))!=EOF) //读取test.txt文件 然后取出字符串,进行对比
{
if(c == ' '||c == '\t'||c == '\n')
{
line[i] = '\0';
Print(line);
printf("%c",c);
i = 0;
continue;
}
line[i++] = c;
}
line[i] = '\0';
Print(line);
fclose(fp);
return 0;
}
欢迎大家一起来交流哈~