您的位置:首页 > 其它

POJ3349总结(第一次用hash解决问题)

2017-09-11 14:01 232 查看

POJ3349(第一次用hash解决问题)

解题思路

1.题目意思比较简单,就是给出一组雪花的数据,然后判断这组雪花里边有没有相同的雪花。也就是判断是否存在两个数组,其所有元素都相同。

2.1暴力破解的思路当然很简单了,每输入一个雪花数据,都将其与已输入数据进行比较;如果存在有相等的,那么就输出“twin snowflakes fount”;否则就继续输入。

2.2第二步中的比较过程则是将两个数组排序后比较对应位。

3.上述思路的代码交上去是time limit exceeded。

4.1这个题目利用hash则会大大提高效率

4.2首先计算一个雪花的hash值,然后将这个雪花放在hash链表的相应位置。如果之前已有相同hash值得雪花存在,那么再把当前雪花与所有已存在的同hash值雪花进行比较。如果没有相同hash值雪花,则说明目前没有与该雪花信息相同的。

4.3上述的hash函数是自定义的,主要目的是将大量的雪花先分堆,然后再进行比较。(因为大量的排序和比较是很耗费时间的,所以hash函数的计算最好是简单却又能将数据分开的)

注意点

1.结构体的定义中。如果当前结构体内部的变量有该结构体类型的指针、或引用了其他结构体,那么被引用的内容需要提前定义或声明。

2.在比较过程中会使用到链表,这里一定要注意逻辑明晰。如下代码,写错的话有可能会出现当前结点最后会和自己进行比较等问题。

while(p!=NULL)
{
//printf("%d%d%d%d%d%d\n",p->info[0],p->info[1],p->info[2],p->info[3],p->info[4],p->info[5]);
for(i=0;i<6;i++)
{
if(p->info[i]!=a->info[i])
{
break;
}
}
if(i==6)
{
return true;
}
pre=p;
p=p->next;
}
pre->next=a;


3.hash计算的时候,取模后计算再取模比较好。防止计算后数过大产生溢出。

int toHash(p_Flake a)
{
int sum=0;
for(int i=0;i<6;i++)
{
sum+=(a->info[i])%100000;
}
return sum%100000;
}


代码

#include<stdio.h>
#include<stdlib.h>

typedef struct SnowFlake{
int info[6];
SnowFlake* next;
}*p_Flake;

#define max 100000

p_Flake hashArray[100000]={NULL};

int toHash(p_Flake a);
bool insertToHash(p_Flake a, int aHash);
void sort(p_Flake a);

int main()
{
int N=0;
scanf("%d",&N);
int flag=0;
for(int k=0;k<N;k++)
{
p_Flake a=NULL;
a=(p_Flake)malloc(sizeof(SnowFlake));
a->next=NULL;
scanf("%d%d%d%d%d%d",a->info,a->info+1,a->info+2,a->info+3,a->info+4,a->info+5);

if(flag==0)
{
if(insertToHash(a,toHash(a))==true)
{
flag=1;
}
}
}
if(flag==1)
{
printf("Twin snowflakes found.\n");
}
else
{
printf("No two snowflakes are alike.\n");
}
return 0;
}

void sort(p_Flake a)
{
for(int i=0;i<6;i++)
{
for(int j=0;j<6-i-1;j++)
{
if(a->info[j+1]<a->info[j])
{
int swap=a->info[j+1];
a->info[j+1]=a->info[j];
a->info[j]=swap;
}
}
}
}

bool insertToHash(p_Flake a, int aHash)
{
int i=0;
sort(a);
if(hashArray[aHash]==NULL)
{
hashArray[aHash]=a;
return false;
}

p_Flake pre=NULL;
p_Flake p=hashArray[aHash];
while(p!=NULL)
{
for(i=0;i<6;i++)
{
if(p->info[i]!=a->info[i])
{
break;
}
}
if(i==6)
{
return true;
}
pre=p;
p=p->next;
}
pre->next=a;
r
4000
eturn false;
}

int toHash(p_Flake a) { int sum=0; for(int i=0;i<6;i++) { sum+=(a->info[i])%100000; } return sum%100000; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj3349 hash