哈希表需要解决的问题:
1.确定函数
2.确定冲突解决办法
3.选择什么样的数据结构进行存储哈希表,开辟多大的空间
解决问题:
1.函数的确定:
如何根据一个字符串来吧函数确定出来呢?
字符串很长,每个字符都有确定的ascii码值,我需要做的就是确定一个计算公式,使得给一个字符串,我可以返回一个值
直接使用长度来确定感觉就很好。这样最多1500的长度,也有利于我进行操作。
故:H(x)=strlen(str)
2.冲突解决办法:
我认为可以直接使用链地址法则,
确定一个结构体,内部由一个字符串和一个next整数组成,数组大小直接开辟11500,这样不可能超出范围,cnt用来记录尾部,从1500之后开始,为前面的首字符串留下空间
步骤:
1.读取总字符串个数
2.循环,读取n个字符串
for
3.每读取一个字符串,字符串哈希计算其长度
4.找到数组对应下标
while(1)
flag0;填入,flag=1,cnt++,break;
flag1,比较
相同,break
不同,判断next
next==0;直接填入当前tail的位置,flag=1;连上
next!=0;直接访问下一位
最后输出cnt即可
字符串比较用strcmp如果相等则返回0;
70分,其实还行,不算太失望,看看到底哪里出了问题把:
数据比对之后,发现我的错误都是在原来基础上多了1?
有意思!
这个错误可还行。
ok
发现错误。原来是将当前字符串填入尾端的时候
发生了
先填值,更新next=tail
tail++
再更新flag=1
顺序错了
应该先flag=1;
再tail++;
把能更新的都更新完再去把tail拨针移动到下一位
大佬的思路:
进制哈希
由于思路较长,所以我们单开一个博文进行书写
[算法学习No14]进制哈希BKDR Hash
bkdr hash代码:
时间复杂度要高一点,除了每次的计算量比较大之外,还有sort函数排序是个大工程(为了查重)
#include<stdio.h>
#include<string.h>
unsigned int arr[10050]={0},k=131,ans,n;
char s[1505];
unsigned int hash()
{
ans=0;
for(int i=1;i<=strlen(s);i++)
{
ans=ans*k+(unsigned int)s[i];
}
return ans;
}
void sort()
{
unsigned int tmp;
for(int gap=n/2;gap>0;gap=gap/2)
{
for(int i=gap+1;i<=n;i++)
{
for(int j=i;j-gap>0&&arr[j]<arr[j-gap];j=j-gap)
{
tmp=arr[j];
arr[j]=arr[j-gap];
arr[j-gap]=tmp;
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",s);
arr[i]=hash();
}
sort();
int cnt=0;
for(int i=1;i<=n;i++)
{
if(arr[i]!=arr[i+1])
{
cnt++;
}
}
printf("%d",cnt);
return 0;
}
我自己的思路的代码:
#include<stdio.h>
#include<string.h>
typedef struct
{
char str[1505];
int next,flag;
}Str;
Str hash[13000];
int tail=1600,cnt=0,n,ind;
char input[1505];
void init()
{
for(int i=1;i<=n;i++)
{
hash[i].flag=0;
hash[i].next=0;
}
}
void Hash()
{
ind=strlen(input);
while(1)
{
if(hash[ind].flag==0)
{
strcpy(hash[ind].str,input);
cnt++;
hash[ind].flag=1;
break;
}
else
{
if(strcmp(hash[ind].str,input)==0)
{
break;
}
else//说明二者并不相等,继续往后遍历
{
if(hash[ind].next==0)//下一位已经没有了,而且当前字符串也不匹配,直接填入了
{
hash[ind].next=tail;
strcpy(hash[tail].str,input);
hash[tail].flag=1;
tail++;
cnt++;
break;
}
else
{
ind=hash[ind].next;
}
}
}
}
}
int main()
{
scanf("%d",&n);
init();
for(int i=1;i<=n;i++)
{
scanf("%s",input);
Hash();
}
printf("%d",cnt);
return 0;
}