如何去掉重复项目效率最高 ( 积分: 15 )

  • 主题发起人 主题发起人 冬月
  • 开始时间 开始时间

冬月

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个LISTBOX中有几十万行数字,需要把相同的去掉,如何效率最高,请给出代码
比如在一个LISTBOX中有如下列:
11111
22222
33333
11111
11111
22222
44444
去掉重复的应该为
33333
44444
 
把listbox值放到数据库里(SQL SERVER)处理可能会快点,不然直接去比较有点慢的
 
不能用数据库,请给出代码,谢谢
 
分数太少,不想动手。
 
用TStringList的Add以及IndexOf两个方法就可以达到楼主的要求。

with TStringList.Create do
begin
Sorted:=true
//设置为已排序,在IndexOf时会自动使用二分法查找
LISTBOX.Items.BeginUpdate
//避免在Delete中刷新界面
for i:=Pred(LISTBOX.Items.Count) downto 0 do //从后向前删
begin
if IndexOf(LISTBOX.Items)>=0 then //检查是否已存在
Delete(i) //如果已存在,就删除
else
Add(LISTBOX.Items)
//如果不存在,就添加进列表
end;
LISTBOX.Items.EndUpdate;
Free;
end;
 
楼上的TStringList替换成THashedStringList就可以了
这个类位于iniFiles单元
原因请看下面的测试结果:

200000 项 TStringList 创建耗时:109毫秒
200 项字符串IndexOf搜索 TStringList 耗时:11514毫秒
200000 项索引搜索 TStringList 耗时:31毫秒
--------------------
200000 项 THashedStringList 创建耗时:108毫秒
200 项字符串IndexOf搜索 THashedStringList 耗时:188毫秒
200000 项索引搜索 THashedStringList 耗时:15毫秒
 
csdn上的一个类似帖子。他这个好像是只查询和删除一个项目吧。
=============
主 题: 关于TXT查找并删除重复数据的问题.大家帮我看看
作 者: zxzcad (小中) Blog
等 级:
信 誉 值: 100
所属社区: Delphi 语言基础/算法/系统设计
问题点数: 20
回复次数: 6
发表时间: 2007-1-3 17:12:35





文本内容如下
aaaa
bbbb
ccc
ddd
aaaa
eee
fff
gggg

怎么样来删除重复的呢~~头疼~





Top
madyak(无天) ( ) 信誉:120 Blog 2007-1-3 17:40:12 得分: 0



procedure TForm1.Button1Click(Sender: TObject);
var
s: TStringList;
I: Integer;
begin
s := TStringList.Create;
....
s.Sort;
for i := s.Count - 1 downto 1 do
if s = s[i - 1] then
s.Delete(i);
...
end;



Top
madyak(无天) ( ) 信誉:120 Blog 2007-1-3 17:42:39 得分: 0



procedure TForm1.Button1Click(Sender: TObject);
var
s: TStringList;
I: Integer;
begin
s := TStringList.Create;
....
s.Sort;
for i := s.Count - 1 downto 1 do
if s = s[i - 1] then
s.Delete(i);
...
end;




Top
zxzcad(小中) ( ) 信誉:100 Blog 2007-1-3 19:27:09 得分: 0



我着这写了,但是问题还是没有解决哦~~aaaa还是没有被删除~~

Lists:=TStringList.Create;
Lists.LoadFromFile(opendialog1.FileName);
progressbar1.Max:=lists.Count-1;
for i:= lists.Count-1 downto 1 do
begin
if lists=lists[i-1] then
begin
lists.Delete(i);
lists.SaveToFile(opendialog1.FileName);
end;
end;



Top
madyak(无天) ( ) 信誉:120 Blog 2007-1-3 19:30:41 得分: 0



是你太粗心,抄错了

Lists:=TStringList.Create;
Lists.LoadFromFile(opendialog1.FileName);
Lists.Sort;
progressbar1.Max:=lists.Count-1;
for i:= lists.Count-1 downto 1 do
begin
if lists=lists[i-1] then
begin
lists.Delete(i);

end;
end;
lists.SaveToFile(opendialog1.FileName);
 
请大家看清楚问题再回答,我要的结果不是列出唯一项目,比如
111,222,333,111通过程序得到222,333,把有相同的项目全部去掉,而不是得到111,222,333这样子.
 
//已经更新过效率问题我没有考虑只是实现要求
procedure TForm1.Button1Click(Sender: TObject);
var
OldStr: String;
StartTime: Cardinal;
I, Count, idx, Oldidx: Integer;
begin
StartTime := GetTickCount;
Count := ListBox1.Items.Count - 1;
I := 0;
while I <= Count do
begin
OldStr := ListBox1.Items;
ListBox1.Items.Delete(I);
Oldidx := I;
idx := ListBox1.Items.IndexOf(OldStr);
if idx < 0 then
begin
ListBox1.Items.Insert(Oldidx, OldStr);
ListBox3.Items.Add(OldStr);
I := Oldidx + 1;
Continue;
end;
ListBox2.Items.Add(OldStr);
while idx >= 0 do
begin
if idx >= 0 then ListBox2.Items.Add(OldStr);
ListBox1.Items.Delete(idx);
idx := ListBox1.Items.IndexOf(OldStr);
end;
Application.ProcessMessages;
Count := ListBox1.Items.Count - 1;
end;
Label4.Caption := '总时间:' + IntToStr(GetTickCount - StartTime);
Label1.Caption := '总数目:' + IntToStr(ListBox1.Items.Count - 1);
Label2.Caption := '总数目:' + IntToStr(ListBox2.Items.Count - 1);
Label3.Caption := '总数目:' + IntToStr(ListBox3.Items.Count - 1);
end;
经测试时间大约花了200 秒左右
 
数字的范围是多少?如果是 1-65535,建议这样做
var data: array[0..65536] of byte;
fillchar(data,.,0);

//处理
for i:=LBData.items.cout-1 downto 0 do
begin
j := strtointdef( LBData.items );
if data[j] < 2 then inc(data[j]);
end;

// 输出结果
for i:= 0 to 65535 do
if data = 1 then memoResult.lines.add(inttostr(i));
 
接受答案了.
 
后退
顶部