哈希

哈希有很多种方法,例如取模(最简单的一种),然而我比较弱,只能写比较丑的代码

(洛谷原题)

如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。

输入输出格式

输入格式:

第一行包含一个整数N,为字符串的个数。

接下来N行每行包含一个字符串,为所提供的字符串。

输出格式:

输出包含一行,包含一个整数,为不同的字符串个数。

输入输出样例

输入样例#1:
5
abc
aaaa
abc
abcc
12345
输出样例#1:
4

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,Mi≈6,Mmax<=15;

对于70%的数据:N<=1000,Mi≈100,Mmax<=150

对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

const
p=9997;
var
child,pre,now:array[0..10000] of longint;
root:array[0..10000] of longint;
d,s:array[0..10000] of ansistring;
sum,i,j,k,n:longint;
procedure ad(x,y:longint);
 begin
  child[y]:=y;
  pre[y]:=now[x];
  now[x]:=y;
 end;
function find(s:ansistring;faa:longint):boolean;
  var
  fa,son:longint;
  begin
  if d[faa]=s then
  exit(true);
  fa:=now[faa];
   while fa<>0 do
    begin
    son:=child[fa];
    if d[son]=s then
     exit(true);
    fa:=pre[fa];
    end;
   find:=false;
  end;
procedure hash(s:ansistring;x:longint);
var
 ans,i,k:longint;
 begin
 ans:=1;
 k:=length(s);
 for i:=1 to k do
 ans:=(ans*ord(s[i])) mod p;
 if root[ans]=0 then
  begin
   root[ans]:=x;
   d[x]:=s;
  end
  else
  begin
   if find(s,root[ans]) then
    exit;
   ad(root[ans],x);
   d[x]:=s;
  end;
  inc(sum);
end;
begin
 sum:=0;
 readln(n);
 for i:=1 to n do
  readln(s[i]);
 for i:=1 to n do
  hash(s[i],i);
  writeln(sum);
end.
View Code

方法据yzw神犇所说,一共有10+26+26=62个字符,用63进制哈希。。

但我比较弱,只能随便拿个数模了

求出每个字符串每个字符的ASCII的编码相乘

如果有冲突用指父链(邻接表)连边

posted @ 2016-11-15 21:32  jkl~  阅读(103)  评论(0编辑  收藏  举报