在 Delphi 6 中使用 Hashtable
Posted lee576
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 Delphi 6 中使用 Hashtable相关的知识,希望对你有一定的参考价值。
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下通过。(其它版本应该也可以,不过没做测试)
工作需要,使用 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下通过。(其它版本应该也可以,不过没做测试)
以上是关于在 Delphi 6 中使用 Hashtable的主要内容,如果未能解决你的问题,请参考以下文章
Delphi 6 -> Delphi 2006 dbexpress 怪异?
delphi 6 中checklistbox中的内容被点选后,显示在messagebox