大数字取mod哈希及拉链法处理冲突

http://hi.baidu.com/mfs666/blog/item/c5ff7c3198e4b01eebc4af91.html

 

本代码即noip2007的第一题,统计数字,有大量重复数字,最好进行哈希判断重复并统计,这里每个数对一个大数字取模,然后进入地址进行拉链查找处理冲突,这种处理冲突的方式基本上是比较和谐的方式

program noip0701;
const
z=1003001;//大质数
type
    node=^b;//指针类型
    b=record//哈希表单元
    c,n:longint;
    l:node;
   end;
Var
h:array[0..z] of node;
m:array[0..10001] of longint;
r:array[0..10001] of node;
tt:node;
i,j,t,n,s:longint;

procedure mfs(a:longint);//写入数字
var
   p,tt:node;
   y:longint;
begin
   y:=a mod z;//取模得地址
   if h[y]=nil then//如果该单元未使用过,直接写入
    begin
     new(h[y]);
     h[y]^.n:=a;
     h[y]^.c:=1;
     inc(s);
     m[s]:=a;
     r[s]:=h[y];
     exit;
    end;
   p:=h[y];
   while p^.n<>a do// 顺着链子寻找一个不再冲突的,直至不冲突
    begin
     if p^.l=nil then //没有不冲突的就新开一个链位,写入并挂在后面
      break;
     p:=p^.l;
    end;
   if p^.n=a then
    inc(p^.c)
   else begin
    new(tt);
    tt^.n:=a;
    tt^.c:=1;
    inc(s);
    m[s]:=a;
    r[s]:=tt;
    p^.l:=tt;
   end;
end;

procedure qs(s,e:longint);
var
   t,i,j,w:longint;
   tp:node;
begin
   i:=s;j:=e;w:=m[(i+j) shr 1];
   repeat
    while m[i]<w do inc(i);
    while m[j]>w do dec(j);
    if i<=j then begin
     tp:=r[i];t:=m[i];
     r[i]:=r[j];m[i]:=m[j];
     r[j]:=tp;m[j]:=t;
     inc(i);dec(j);
    end;
   until i>j;
   if i<e then qs(i,e);
   if j>s then qs(s,j);
end;


begin
assign(input,'in.in');reset(input);

readln(n);
for i:=1 to n do begin
   readln(t);
   mfs(t);
end;
qs(1,s);
for i:=1 to s do
   writeln(m[i],' ',r[i]^.c);
end.

posted @ 2010-05-14 13:38  jesonpeng  阅读(259)  评论(0)    收藏  举报