正文
Delphi中的THashTable
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
在Delphi中,Inifiles单元中有一个TStringHash的类,不过它的Value仅支持Integer(其实也不是问题,有其它类型可以将变量变为Pointer),有点不舒服,今天没事做就把它替换为variant了,其中Key的名称大小写无关,就是为了加快开发速度!
使用Hashtable,查找和删除复杂度都是常数级别的!
type
PPHashItem = ^PHashItem;
PHashItem = ^THashItem;
THashItem = record
Next: PHashItem;
Key: String;
Value: Variant;
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: Cardinal = );
destructor Destroy; override;
procedure Put(const Key: String; Value: Variant);
procedure Clear;
procedure Remove(const Key: String);
function Modify(const Key: String; Value: Variant): Boolean;
function Get(const Key: String): Variant;
function ContainKey(const Key: String):boolean;
end;
procedure THashTable.Clear;
var
I: Integer;
P, N: PHashItem;
begin
for I := to Length(Buckets) - do
begin
P := Buckets[I];
while P <> nil do
begin
N := P^.Next;
Dispose(P);
P := N;
end;
Buckets[I] := nil;
end;
end;
function THashTable.ContainKey(const Key: String): boolean;
var
P: PHashItem;
begin
P := Find(Key)^;
if P <> nil then
begin
Result := True;
end
else
Result := False;
end;
constructor THashTable.Create(Size: Cardinal);
begin
inherited Create;
SetLength(Buckets, Size);
end;
destructor THashTable.Destroy;
begin
Clear;
inherited Destroy;
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.Get(const Key: String): Variant;
var
P: PHashItem;
begin
P := Find(AnsiUpperCase(Key))^;
if P <> nil then
Result := P^.Value
else
Result := -;
end;
function THashTable.HashOf(const Key: String): Cardinal;
var
I: Integer;
begin
Result := ;
for I := to Length(Key) do
Result := ((Result shl ) or (Result shr (SizeOf(Result) * - ))) xor
Ord(Key[I]);
end;
function THashTable.Modify(const Key: String; Value: Variant): 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.Put(const Key: String; Value: Variant);
var
Hash: Integer;
Bucket: PHashItem;
begin
Hash := HashOf(AnsiUpperCase(Key)) mod Cardinal(Length(Buckets));
New(Bucket);
Bucket^.Key := AnsiUpperCase(Key);
Bucket^.Value := Value;
Bucket^.Next := Buckets[Hash];
Buckets[Hash] := Bucket;
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;
使用:
var
Demo:THashTable;
begin
Demo:=THashTable.Create();
try
Demo.Put('id',);
ShowMessage(Demo.Get('id'));
finally
Demo.Free;
end;
end;
参考:http://www.cnblogs.com/key-ok/p/3358929.html