TList中搜索的问题 ( 积分: 200 )

  • 主题发起人 主题发起人 huangliang2005
  • 开始时间 开始时间
H

huangliang2005

Unregistered / Unconfirmed
GUEST, unregistred user!
如何在两个TList搜索相同的记录然后提取出来,这两个TList中存的数据是一个结构类型,两个TList中存的是两种数据,只有一个ID可以对应,怎么从这两个TList中搜索相同ID的数据,TList的数据量都比较,而且不能确定有多少条记录.由于处理的数据多而且不固定,要最优的最法
 
你说得稀里糊涂,应该条理清楚些.
 
to:wan_yi
我从采集程序中把采集的数据以一个结构形式存放,然后把这些数据存放在TList中,由于是两种不同的数据,所以要用到两个TList,存放数据的结构是相同的,这两个TList中的数据都有一个ID对应,要找出有相同ID的记录
比如:
TIMSI = packed record
a1:integer;
a2:integer;
a3:string;
ID:integer;
end;
PTIMSI = ^TIMSI;
MyList1,MyList2:TList;
其中MyList1中存放的是a1,a3,ID,TList2中存放的是a2,ID,根据MyList1和MyList2中的ID的对应关系来找出相同的记录,其中MyList1,MyList2中的数据量非常大,而且不知道有多少,要用最优的算法.
 
建议用数据库,数据库就是干这个的。
或者 去看看hashtable ,不过我这里没有例子。找找实现方式。
 
呵呵找到了,应该能解决你的问题。
不过这个的 value 是 String 你修改为Object 就可以了。
以下:
不必白手起家,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;
while P <> nil do
begin
N := P^.Next;
Dispose(P);
P := N;
end;
Buckets := 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);
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; //撤消
 
你在需查找的TList上Sort,并保持Sorted=true,这样,你可以用Find来查找了。Find是用二分法来查找的,速度特快。[:)]
 
用Tstringlist就可以解决,如果要求效率,可以考虑哈希.
 
发了一段代码到你的邮箱里去了,你看一下,应该可以用的
 
接受答案了.
 
后退
顶部