在 Delphi 6 中使用 Hashtable

news/2024/7/3 13:35:34 标签: delphi, string, integer, function, destructor, constructor
Java 中的 Hashtable 类小巧好用,尤其是因为采用了哈希算法,查找的速度奇快。后来因
工作需要,使用 Delphi 实施一些项目,特别不习惯没有哈希表的日子。于是决定自己动手做
一个。
  不必白手起家,Delphi 中有一个 THashedStringList 类,它位于 IniFiles 单元中。它里面
有一个不错的哈希算法,解决冲突的机制是“链地址”。把这个类改装改装,就成了自己的
了。新鲜热辣,火爆出炉。下面就来看看新的 Hashtable 长得何许模样。

                    Hashtable.pas
--------------------------------------------------------------------------------
    unit Hashtable;
   
    interface
   
    uses SysUtils, Classes;
   
    type
      { THashTable }
   
      PPHashItem = ^PHashItem;
      PHashItem = ^THashItem;
      THashItem = record
      Next: PHashItem;
      Key: string;
      Value: String;
      end;
   
      THashTable = class
      private
      Buckets: array of PHashItem;
      protected
      function Find(const Key: string): PPHashItem;
      function HashOf(const Key: string): Cardinal; virtual;
      public
      constructor Create(Size: Integer = 256);
      destructor Destroy; override;
      procedure Put(const Key: string; Value: String);
      procedure Clear;
      procedure Remove(const Key: string);
      function Modify(const Key: string; Value: String): Boolean;
      function Get(const Key: string): String;
      end;
   
    implementation
   
    { THashTable }
   
    procedure THashTable.Put(const Key: string; Value: String);
    var
      Hash: Integer;
      Bucket: PHashItem;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
      New(Bucket);
      Bucket^.Key := Key;
      Bucket^.Value := Value;
      Bucket^.Next := Buckets[Hash];
      Buckets[Hash] := Bucket;
    end;
   
    procedure THashTable.Clear;
    var
      I: Integer;
      P, N: PHashItem;
    begin
      for I := 0 to Length(Buckets) - 1 do
      begin
      P := Buckets[I];
      while P <> nil do
      begin
        N := P^.Next;
        Dispose(P);
        P := N;
      end;
      Buckets[I] := nil;
      end;
    end;
   
    constructor THashTable.Create(Size: Integer);
    begin
      inherited Create;
      SetLength(Buckets, Size);
    end;
   
    destructor THashTable.Destroy;
    begin
      Clear;
      inherited;
    end;
   
    function THashTable.Find(const Key: string): PPHashItem;
    var
      Hash: Integer;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
      Result := @Buckets[Hash];
      while Result^ <> nil do
      begin
      if Result^.Key = Key then
        Exit
      else
        Result := @Result^.Next;
      end;
    end;
   
    function THashTable.HashOf(const Key: string): Cardinal;
    var
      I: Integer;
    begin
      Result := 0;
      for I := 1 to Length(Key) do
      Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
        Ord(Key[I]);
    end;
   
    function THashTable.Modify(const Key: string; Value: String): Boolean;
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
      begin
      Result := True;
      P^.Value := Value;
      end
      else
      Result := False;
    end;
   
    procedure THashTable.Remove(const Key: string);
    var
      P: PHashItem;
      Prev: PPHashItem;
    begin
      Prev := Find(Key);
      P := Prev^;
      if P <> nil then
      begin
      Prev^ := P^.Next;
      Dispose(P);
      end;
    end;
   
    function THashTable.Get(const Key: string): String;
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
      Result := P^.Value else
      Result := '';
    end;
   
    end.
--------------------------------------------------------------------------------

使用起来就简单了:
HashTable := THashTable.Create(); //创建
HashTable.Put(Key, Value);       //赋值
Value=HashTable.Get(Key);       //取值
HashTable.Destroy;           //撤消

本程序在Delphi 6.0下通过。(其它版本应该也可以,不过没做测试)

 

http://www.niftyadmin.cn/n/1415370.html

相关文章

ArcGIS无法创建FeatureDataset问题解决

管理员身份登陆数据库&#xff0c;授权EnableEnterpriseGeodatabase > sqlplus / as sysdbaGRANT EXECUTE ON DBMS_PIPE TO public; GRANT EXECUTE ON DBMS_LOCK TO public; GRANT EXECUTE ON DBMS_UTILITY TO public; GRANT EXECUTE ON DBMS_SQL TO public; GRANT EXECUTE…

高屋建瓴:梳理编程约定

相关文章连接&#xff1a; 编程之基础&#xff1a;数据类型&#xff08;一&#xff09; 编程之基础&#xff1a;数据类型&#xff08;二&#xff09; 动力之源&#xff1a;代码中的“泵” 完整目录与前言 高屋建瓴&#xff1a;梳理编程约定 2.1 代码中的Client与Server 212.…

谁说Delphi没有哈希?--Delphi中,TStringList和THashedStringList的性能对比

曾经看到很多人在嚷嚷Delphi没有哈希表&#xff0c;这些人的动手意识姑且不论&#xff0c;却还有很多人以此来证明Delphi比别的语言垃圾&#xff0c;实在是... 好&#xff0c;牢骚打住&#xff0c;转接正题。 TStringList是我们常用的字符串列表类型&#xff0c;用法就不在这…

(干货)命令之镜像

1.获取镜像 docker pull # 从官方获取ubuntu仓库标记为12.04的镜像   docker pull alpine:3.2 # 从第三方registry.hub.docker.com获取ubuntu仓库标记为12.04的镜像   docker pull registry.hub.docker.com/alpine:3.2 运行docker run -t -i alpine:3.2 /bin/bash启动镜像 …

AcrGIS批量注册图形表到地理数据库

场景描述 在Oracle中处理ArcGIS数据时&#xff0c;有时候需要创建全国各省份的图形表&#xff0c;如GP_PROVINCE_00…&#xff0c;一般有两种方式&#xff1a; 方法1-在数据库中批量新建图形表&#xff0c;然后在ArcGIS中进行注册&#xff0c;也就是指定objectid&#xff1b;…

什么是利基市场 我关注的几个利基市场中的技术 关于程序员买房的选择和想法...

Wake up every day with a feeling of passion for the difference technology will make in peoples life! —— 啤酒盖子 事后诸葛是最无聊的&#xff0c;“我就说……”&#xff0c;“我以前就说过……”&#xff0c;这类话的技术含量太低&#xff0c;近乎等于0。更重…

带按钮的CxGrid

使用 CxGrid 制作出类似于网页上的数据表格效果&#xff0c;每条记录后都能带有按钮。通过按钮去控制指定的记录。 程序截图&#xff1a; 关键的设置在 DFM 中&#xff1a;object Form1: TForm1Left 0Top 0Caption Form1ClientHeight 217ClientWidth 460Color clBtnFaceF…

AcrGIS批量操作mxd发布动态服务

场景描述 在使用ArcGIS发布服务时&#xff0c;经常会因为数据量大而卡死&#xff0c;部分原因是因为ArcGIS本身图形渲染和组件占用内存较多&#xff0c;使用Arcpy进行批量发布可以较好的规避这个问题。 实践示例 批量发布动态服务 #coding:utf-8 import arcpy,os,logging# …