10391 - Compound Words(***)字符串的哈希函数

/*
题意:一组单词,是否可以分解成两个单词

思路:可以进行重组(一种时间效率为n,但空间分配为n*n,一种时间效率为n*n,空间分配为n)
也可以进行分拆,效率为n*m,其中m为单词平均长度。
主要学习:字符串的哈希处理

另外看别人的代码学习到的新技巧:
char str[n][m];
int r[n];
借助r来实现对str的排序。
步骤:
for(int i=0;i<n;i++)
r[i]=i;
qsort(r,n,sizeof(r[0]),cmp);
for(int i=0;i<n;i++)
printf("%s\n",str[r[i]]);
其中:
int cmp(const void *a,const void *b)
{
int *pa=(int *)a;
int *pb=(int *)b;
return strcmp(str[pa],str[pb]);
}
*/

#include <cstdio>
#include <cstring>
const int nMax=120007;
int head[nMax],next[nMax];
char str[nMax][100];
int hash(char *a)
{
	int u=0;
	while(*a)
	{
		u=u*26+*a;
		a++;
	}
	return (u & 0x7fffffff)%nMax;
}
void insert(int k)
{
	int h=hash(str[k]);
	next[k]=head[h];
	head[h]=k;
}
bool search(char *a)
{
	int h=hash(a);
	int ok=false;
	for(int i=head[h];i!=-1;i=next[i])
		if(strcmp(str[i],a)==0)
		{
			ok=true;
			break;
		}
	return ok;
}
int main()
{
	//freopen("data.in","r",stdin);
	int n=0;
	memset(head,-1,sizeof(head));
	while(gets(str[n]))
	{
		insert(n);
		n++;
	}
	for(int i=0;i<n;i++)
	{
		for(int j=1;j<strlen(str[i]);j++)
		{
			char str1[100],str2[100];
			memset(str1,0,sizeof(str1));
			memset(str2,0,sizeof(str2));
			strncpy(str1,str[i],j);
			strncpy(str2,str[i]+j,strlen(str[i])-j);
			if(search(str1) && search(str2))
			{
				printf("%s\n",str[i]);
				break;//原来这里忘了跳出,一直WA。正所谓细节决定成败!
			}
		}
	}
	return 0;
}

第二次做:

#include <cstdio>
#include <cstring>
const int nMax=120000+10;
const int HASH=10000000;
char words[nMax][50];
int hash[HASH],next[HASH];
int get_hash(char word[])
{
	int num,len;
	len=strlen(word);
	num=0;
	for(int i=0;i<len;i++)
		num=num*10+word[i];
	return (num & 0x7fffffff)%HASH;
}
bool is_find(char a[])
{
	int p=get_hash(a);
	p=hash[p];
	while(p!=-1)
	{
		if(strcmp(words[p],a)==0) return true;
		p=next[p];
	}
	return false;
}
bool handle(int k)
{
	int len=strlen(words[k]);
	for(int i=1;i<len;i++)
	{
		char a[50],b[50];
		strncpy(a,words[k],i);
		a[i]=0;
		strncpy(b,words[k]+i,len-i);
		b[len-i]=0;
		if(is_find(a) && is_find(b))
			return true;
	}
	return false;
}
int main()
{
	//freopen("f://data.in","r",stdin);
	int n=0;
	memset(hash,-1,sizeof(hash));
	memset(next,-1,sizeof(next));
	while(scanf("%s",words[n])==1)
	{
		int p=get_hash(words[n]);
		next[n]=hash[p];
		hash[p]=n;
		n++;
	}
	for(int i=0;i<n;i++)
		if(handle(i))
			printf("%s\n",words[i]);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值