UVA 10391 - Compound Words 字符串hash

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1332

题目大意:

给定一个词典(已经按照字典序排好),要求找出其中所有的复合词,即恰好由两个单词连接而成的单词。(按字典序输出)

思路:

对于每个单词,存入Hash表,然后对每个单词拆分。

Hash函数的选取可以看:https://www.byvoid.com/blog/string-hash-compare/

我的这个是BKDRHash。

乘以一个比他大的素数。

关于:0x7fffffff(即int_max,最大的整型范围。why? 16进制每位由4个二进制表示,7二进制位0111,其他的f为1111.)


#include<cstdio>
#include<cstring>
const int MAXN=120000+10;
int head[MAXN],len,n;
char data[MAXN][30];
typedef unsigned long long LL;
struct edge
{
	int index,next;
}e[MAXN];

int gethash(char *s)
{
	LL seed=131;
	LL res=0;
	int L=strlen(s);
	for(int i=0;i<L;i++)
	{
		res=res*seed+s[i];
	}
	return (res& 0x7fffffff )% MAXN;
}

void add(char *s,int index)
{
	int id=gethash(s);
	e[len].index=index;
	e[len].next=head[id];
	head[id]=len++;
}
bool find(char *s)
{
	int id=gethash(s);
	for(int i=head[id];i!=-1;i=e[i].next)
	{
		int index=e[i].index;
		if(strcmp(s,data[i])==0)
			return true;
	}
	return false;
}
int main()
{
	n=len=0;
	memset(head,-1,sizeof(head));
	while(~scanf("%s",data[n]))
	{
		add(data[n],n);
		n++;
	}

	for(int i=0;i<n;i++)
	{
		int L=strlen(data[i]);
		L--;
		for(int j=1;j<L;j++)
		{
			char temp[30];
			strcpy(temp,data[i]+j);
			char flag=data[i][j];
			data[i][j]='\0';
			if(find(data[i]) && find(temp))
			{
				data[i][j]=flag;
				puts(data[i]);
				break;
			}
			data[i][j]=flag;
		}
	}
	
	return 0;
}


你可能感兴趣的:(编程,ACM,uva)