现在我的TList中有很多与坐标有关的内容,大概有30万条,如:
10-10-1
10-10-2
10-10-3
20-10-2
20-10-1
10-10-4
前面的是x和y坐标,最后一位是该坐标的标记,我现在需要把坐标相同的只保留最后面的一条,处理后的结果如下:
20-10-1
10-10-4
哪位大侠帮个忙啊!!!
10-10-1
10-10-2
10-10-3
20-10-2
20-10-1
10-10-4
前面的是x和y坐标,最后一位是该坐标的标记,我现在需要把坐标相同的只保留最后面的一条,处理后的结果如下:
20-10-1
10-10-4
哪位大侠帮个忙啊!!!
用另一个TList做记录。在原本TList从第一笔到最后一笔,取出前四位成索引,
设置新List[Index]='A'最后,新List从0-9999跑一圈,凡值是'A'的就是所有内容。
如果我说的没错,用排序会更慢。其实,更正确的做法是在获得数据时就用我上述方案的新List处理,
那就飞快,完全没有遍历的问题。
2.不想写代码的话,可把数据保存至数据库的表里,用SQL处理
30W要遍历还是费时间的,LS说的,在数据库里面做,这样高效点。
个人觉得还是算法好,那么可以解决很多问题
二,引入ID列,给每条数据引入唯一标识;
三,将你的这一个字段拆为两个字段,10-10-1拆成10-10-,1
四,用GROUP BY HAVING COUNT 函数查出重复数据的所有最大ID(不知道怎么用可以百度查),
五,删除非最大ID数据;
六,将两个字段合成一个字段。
piXMax = 4000; //假设X最大值
piYMax = 3000; //假设Y最大值
type
TXYList = array [0..piXMax*piYMax-1] of Byte;
PXYList = ^TXYList;function SplitStr(Const sLine : String; var xy : integer) : Boolean;
var
i , x , y : integer;
P : PChar;
begin
Result := False;
if sLine='' then exit;
P := Pointer(sLine);
x := -1;
y := -1;
for i:=0 to Length(sLine)-1 do begin
if P[i]='-' then begin
if x<0 then x := i
else begin
y := i;
Break;
end;
end;
end;
if y<=0 then exit;
if TryStrToInt(Copy(sLine , 1 , x) , xy) then begin
xy := xy * piYMax;
if TryStrToInt(Copy(sLine , x+2 , y-x-1) , y) then begin
xy := xy + y;
Result := y<piYMax;
end;
end;
end;procedure RemoveXYRep(InList , OutList : TStringList);
var
i , xy : integer;
List : PXYList;
sLine : String;
begin
GetMem(List , SizeOf(List^));
FillChar(List^ , SizeOf(List^) , 0);
OutList.BeginUpdate;
OutList.Clear;
for i:=InList.Count-1 downto 0 do begin //从后往前搜索
sLine := InList.Strings[i];
if SplitStr(sLine , xy) then begin //计算所引
if List[xy]=0 then begin //如果x,y不存在
List[xy] := 1; //设置为存在
OutList.Add(sLine); //增加到OutList中,从后往前增加
end;
end;
end;
//把顺序倒过来
xy := OutList.Count-1;
for i:=0 to OutList.Count DIV 2 - 1 do begin
OutList.Exchange(i , xy-i);
end;
OutList.EndUpdate;
FreeMem(List);
end;