⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cphset.pas

📁 生物信息学中的遗传数据分析的delphi源码。
💻 PAS
字号:
{$I CPDIR.INC}

{*

   Hash table for clusters

   2/13/91  First version

   3/19/91  Memory error checking added.


   BM(NH)

   6 Feb 1992  Uses NEWLOG text file device driver
  28 Jan 1993  []

*}

{*
   Objects
   -------

   HASH_TABLEOBJ
*}


unit cphset;

interface

uses
   cpmem,    { heap error handling }
   cpwbuf,   { display buffer }
   cpset;    { cluster }

const
   HASHTABLESIZE = 1991;
   HASH_M1       = HASHTABLESIZE - 1;

type
   HASH_BUCKET = record
      count    : integer;
      contents : CLUSTEROBJ;
      end;
   HASH_BUCKET_PTR = ^HASH_BUCKET;

   HASHTABLEPTR = ^HASH_TABLEOBJ;
   HASH_TABLEOBJ = object
      constructor Init;
      destructor Done;
      function IsEmpty(i:integer):Boolean;
      function ReturnCount(i:integer):integer;
      function ReturnClusterPtr(i:integer):CLUSTEROBJ_PTR;
      procedure Show (Range:integer);
      function Insert (var S:CLUSTEROBJ):integer;
      procedure FirstBucket (var C:CLUSTEROBJ; var F:integer);
      procedure NextBucket (var C:CLUSTEROBJ; var F:integer);
      function MoreBuckets:Boolean;

      private
      H: array[0..HASH_M1] of HASH_BUCKET_PTR;
      Buckets    : 0..HASH_M1;  { no. of occupied buckets }
      Count      : 0..HASH_M1;  { local counter }
      LastBucket : 0..HASH_M1;
      function NonEmptyBucket:integer;
      end;

implementation

   constructor HASH_TABLEOBJ.Init;
   var
      i: 0..HASH_M1;
   begin
      Buckets := 0;
      Count   := 0;
      for i := 0 to HASH_M1 do
         H[i] := NIL;
   end;

   destructor HASH_TABLEOBJ.Done;
   var
      i: 0..HASH_M1;
   begin
      for i := 0 to HASH_M1 do
         if (H[i] <> NIL) then
            Dispose (H[i]);
   end;

{---HASH_TABLEOBJ Queries---}

   function HASH_TABLEOBJ.IsEmpty(i:integer):Boolean;
   { TRUE if ith cell is empty }
   begin
      IsEmpty := (H[i] = NIL);
   end;

   function HASH_TABLEOBJ.ReturnCount(i:integer):integer;
   begin
      ReturnCount := H[i]^.Count;
   end;

   function HASH_TABLEOBJ.ReturnClusterPtr(i:integer):CLUSTEROBJ_PTR;
   begin
      ReturnClusterPtr := @H[i]^.Contents;
   end;

   procedure HASH_TABLEOBJ.Show (Range:integer);
   var
      {$IFDEF DEVICE}
      s: string;
      {$ENDIF}
      i, j: integer;
   begin
      {$IFDEF DEVICE}
      writeln (NEWLOG);
      writeln (NEWLOG, 'Cluster table');
      writeln (NEWLOG);
      Label_Cols (4,10,Range);
      j := 0;
      for i := 0 to HASH_M1 do
         if (H[i] <> NIL) then begin
            Inc (j);
            write (NEWLOG, j:3, ' ');
            H[i]^.Contents.DisplaySet (Range);
            writeln (NEWLOG, H[i]^.Count:5);
            end;
      writeln (NEWLOG);
      {$ELSE}
      DisplayBuffer.InsertNewLine;
      DisplayBuffer.InsertATitle ('Cluster table');
      Label_Cols (4,10,Range);
      Buffer.Clear;
      j := 0;
      for i := 0 to HASH_M1 do
         if (H[i] <> NIL) then begin
            Inc (j);
            Str (j:3, s);
            Buffer.AppendString (s + ' ');
            H[i]^.Contents.DisplaySet (Range);
            Str (H[i]^.Count:5, s);
            Buffer.AppendString (s);
            DisplayBuffer.InsertLineBuffer (Buffer);
            Buffer.Clear;
            end;
      DisplayBuffer.InsertNewLine;
      {$ENDIF}
   end;

   function HASH_TABLEOBJ.Insert (var S:CLUSTEROBJ):integer;
   { Insert cluster S into hash table, return codes:
      -2: No memory
      -1: Hash table overflow
       0: Successful
   }
   const
      PROBELENGTH = 1;
   var
      ocode,
      hcode : integer;
      Finished  : Boolean;
   begin
      Insert := 0;
      hcode := S.HCode (HASHTABLESIZE);
      ocode := hcode;
      Finished  := FALSE;
      while not Finished do begin
         if (H[hcode] = NIL) then begin
            { Cell is vacant }
            GetMem (H[hcode], SizeOf (HASH_BUCKET));
            if (H[hcode] = NIL) then begin
               Insert := -2;
               Exit;
               end
            else Inc (Buckets);
            H[hcode]^.count   := 1;
            H[hcode]^.contents.NullSet;
            H[hcode]^.contents.AddSetToSet (S);
            Finished          := TRUE;
            end
      else begin
         { Cell is occupied }
         if (S.Relationship (H[hcode]^.contents) = IDENTITY) then begin
            { Cell is the same }
            Inc (H[hcode]^.Count);
            Finished := TRUE;
            end
         else begin
            { Cell is different, resolve collision by linear probing }
            hcode := hcode + PROBELENGTH;
            if (hcode > HASH_M1) then
               hcode := 0;
            if (hcode = ocode) then begin
               Insert := -1;
               Exit;
               end;
            end;
         end;
      end;
   end;

{----------------------------------------------------------------------------}

   function HASH_TABLEOBJ.NonEmptyBucket:integer;
   var
      i: integer;
   begin
      i := Succ (LastBucket);
      while (H[i] = NIL) do
         Inc (i);
      LastBucket := i;
      NonEmptyBucket := i;
   end;


   procedure HASH_TABLEOBJ.FirstBucket (var C:CLUSTEROBJ; var F:integer);
   var
      i: integer;
   begin
      LastBucket := 0;
      Count      := 1;
      i := NonEmptyBucket;
      C.NullSet;
      C.AddSetToSet (H[i]^.contents);
      F := H[i]^.count;
   end;

   procedure HASH_TABLEOBJ.NextBucket (var C:CLUSTEROBJ; var F:integer);
   var
      i: integer;
   begin
      i := NonEmptyBucket;
      Inc (Count);
      C.NullSet;
      C.AddSetToSet (H[i]^.contents);
      F := H[i]^.count;
   end;

   function HASH_TABLEOBJ.MoreBuckets:Boolean;
   begin
      MoreBuckets := (Count < Buckets);
   end;





end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -