您的位置:首页 > 其它

使用数组实现快速数据查找

2005-11-08 22:14 501 查看
在很多数据库应用程序中,需要通过一个关键字段找出对应的其它字段数据,并且要求查找速度快。如在大多数的监控程序中,从终端获得一个标识后,需要通过这个标识将数据表中的其它数据查询出来,并显示在程序界面上。一般的做法是直接使用SQL查询返回查询结果。其实如果这个标识是唯一有序的,并且返回的结果也是唯一的,就没必要频繁地查询数据库。应该将数据首先存入内存,当然数据行上万就有难度。我要讲的存入内存其实是采用最为简单的方式,也就是记录(结构)类型作元素的数组。
具休做法是,先定义一个记录类型,用于保存在界面中要显示的结果数据,再定义一个数组,将所有数据从数据表是查询并排序存入这个数组。在查找时使用二分法得到对应的数组元素。
具体代码如下:
unitu_MyData;
interface
uses
 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,
 Dialogs,StdCtrls,DB;
type
 PMyData=^TMyData;
 TMyData=record
   CardNo:Integer;
   EmpNo,EmpName,ClassName:String;
 end;
 TMySearch=class
 private
   {Privatedeclarations}
   List:ArrayofTMyData;
   functionSearch(iBegin,iEnd,ACardNo:Integer):Integer;
 public
   {Publicdeclarations}
   destructorDestroy;override;
   functionClear:Boolean;
   functionLoadValue(Items:TStrings):Boolean;overload;
   functionLoadValue(DataSet:TDataSet):Boolean;overload;
   functionSearchFor(ACardNo:Integer):TMyData;overload;
 end;
var
 NULL_DATA:TMyData;
implementation
{TMySearch}
functionTMySearch.Clear:Boolean;
begin
 Result:=False;
 try
   SetLength(List,0);
   Result:=True;
 except
   //Can'tfreetheelement.
 end;
end;
destructorTMySearch.Destroy;
begin
 Clear;
 inherited;
end;
functionTMySearch.LoadValue(DataSet:TDataSet):Boolean;
var
 i:integer;
begin
 Result:=False;
 try
   Clear;     //Cleartheoldvaluefirst.
   withDataSetdo
   begin
     ifActivethen
     begin
       DisableControls;
       try
         SetLength(List,RecordCount);
         First;
         fori:=0toRecordCount-1do
         begin
           List[i].CardNo:=Fields[0].AsInteger;
           List[i].EmpNo:=Fields[1].AsString;
           List[i].EmpName:=Fields[2].AsString;
           List[i].ClassName:=Fields[3].AsString;
           Next;
         end;
       finally
         EnableControls;
       end;
     end;
   end;
 except
   //Can'tloadvaluefromdataset.
 end;
end;
functionTMySearch.LoadValue(Items:TStrings):Boolean;
var
 i:integer;
begin
 Result:=False;
 try
   Clear;     //Cleartheoldvaluefirst.
   
   SetLength(List,Items.Count);
   fori:=0toItems.Count-1do
   begin
     List[i].CardNo:=StrToInt(Items[i]);
   end;
   Result:=True;
 except
   //Can'tloadvaluefromstrings.
 end;
end;
functionTMySearch.Search(iBegin,iEnd,ACardNo:Integer):Integer;
var
 Mid:Integer;
begin
 Result:=-1;
 try
   ifiBegin<=iEndthen
   begin
     Mid:=(iBegin+iEnd)div2;
     ifList[Mid].CardNo=ACardNothen
       Result:=Mid
     elseifList[Mid].CardNo>ACardNothen
       Result:=Search(iBegin,Mid-1,ACardNo)
     else
       Result:=Search(Mid+1,iEnd,ACardNo);
   end;
 except
   //Can'tsearchthevalue.
 end;
end;
functionTMySearch.SearchFor(ACardNo:Integer):TMyData;
var
 i:integer;
begin
 Result:=NULL_DATA;
 try
   ifLength(List)>0then
   begin
     i:=Search(0,Length(List)-1,ACardNo);
     if(i>=0)and(i<Length(List))then
       Result:=List[i];
   end;
 except
   //Can'tfindavalue.
 end;
end;
end.
{以一个类实现} 
以上代码经测试,只是感觉上比查询数据库快,实际还得设定相同条件进行比较。
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息