【问题标题】:How to skip out of this loop?如何跳出这个循环?
【发布时间】:2010-11-28 13:42:22
【问题描述】:

这是一个在 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 的索引是通过二分查找得到的。

非常感谢。

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

【问题讨论】:

  • 既然您知道使用二进制印章来查找范围的第一个和最后一个元素,您似乎已经回答了自己的问题。您究竟需要什么帮助?

标签: delphi


【解决方案1】:

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

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

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

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

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(pointer(List[i]))^=V 是 copy(List[i],1,2)=Char1+Char2 的更快版本,因为在比较过程中不会创建临时字符串。但它只有在没有 List[i]='' 时才有效,即没有指针(List[i])=nil。

我添加了一个 {$ifdef UNICODE} 和 sizeof(char) 以使该代码能够与所有版本的 Delphi 一起编译(在 Delphi 2009 之前和之后)。

【讨论】:

  • 亲爱的 A.Bouchez:非常感谢您提供如此详细而清晰的回答。
【解决方案2】:

要停止运行循环,请使用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;

【讨论】:

  • 亲爱的 Rob Kennedy: 再次感谢您立即明确的答复。我们没有添加found标志,而是使用了'for ...loop',所以性能低下。
猜你喜欢
  • 2015-04-08
  • 2016-04-08
  • 2020-08-08
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
相关资源
最近更新 更多