如何跳过这个循环?

时间:2010-11-28 13:42:22

标签: delphi

这是一个排序列表视图,在delphi中有50000个项目(字符串)。如何快速搜索具有相同前缀单词的项目,然后跳过循环?

列表如下:

aa.....
ab cd//from here
ab kk
ab li
ab mn
ab xy// to here
ac xz
...

我的意思是如何快速查找和复制前缀为ab的项目并跳过循环。假设在二元搜索中得到一个ab项的索引。 ab cd到ab xy的索引是通过二进制搜索得到的。

非常感谢。

编辑:我们感谢大家的回答。

2 个答案:

答案 0 :(得分:7)

如果您想要快速的东西,请不要将数据存储在TListView中。

使用TStringList存储列表,然后在虚拟模式下使用TListView。

从TStringList.Items []读取比从TListView.Items []属性读取要快许多倍。

如果您确定列表中不存在无效项,请使用:

procedure Extract(List, Dest: TStrings; Char1, Char2: char);
var i,j: integer;
    V: cardinal;
type PC = {$ifdef UNICODE}PCardinal{$else}PWord{$endif};
begin
  V := ord(Char1)+ord(Char2) shl (8*sizeof(char));
  Dest.BeginUpdate;
  Dest.Clear;
  for i := 0 to List.Count-1 do begin
  if PC(pointer(List[i]))^=V then begin
    for j := i to List.Count-1 do begin
      Dest.Add(List[j]);
      if PC(pointer(List[j]))^<>V then
        break; // end the for j := loop
     end;
     break; // end the for i := loop
  end;
  Dest.EndUpdate;
end;

您可以使用二进制搜索来更快地获得它。但是使用PWord()技巧,在50000项目列表中,您将不会注意到它。

请注意,PC(指针(List [i]))^ = V是复制的更快版本(List [i],1,2)= Char1 + Char2,因为在比较期间不会创建临时字符串。但它只有在没有List [i] =''时才有效,即没有指针(List [i])= nil。

我添加了一个{$ ifdef UNICODE}和sizeof(char),以便使用所有版本的Delphi(在Delphi 2009之前和之后)编译此代码。

答案 1 :(得分:5)

要停止运行循环,请使用break命令。 Exit对于保留整个函数也很有用,尤其是当您有多个嵌套循环要转义时。作为最后的手段,您可以使用goto跳出几个嵌套循环并继续在同一个函数中运行。

如果您使用whilerepeat循环而不是for循环,则可以在停止条件中包含另一个设置为中间循环的合取:

i := 0;
found := False;
while (i < count) and not found do begin
    // search for items
    found := True;
    // more stuff
    Inc(i);
end;