Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to skip out of this loop?

Tags:

delphi

This is a sorted listview with 50000 items(strings) in delphi. How to fast search items with same prefixed words and then skip out loop?

The list is like:

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

I mean how to fast find and copy items with prefixes of ab and skip out loop. Suppose index of one of ab items is got in a binarysearch. The index of ab cd to ab xy is got through a binary search.

Thank you very much.

Edit: We thank all for your answers.

like image 629
Dylan Avatar asked Dec 10 '22 12:12

Dylan


2 Answers

If you want something fast, don't store your data in a TListView.

Use a TStringList to store your list, then use a TListView in virtual mode.

Reading from a TStringList.Items[] is many times faster than reading from a TListView.Items[] property.

If you're sure that no void item exist in the list, uses this:

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;

You can use binary search to get it even faster. But with the PWord() trick, on a 50000 items list, you won't notice it.

Note that PC(pointer(List[i]))^=V is a faster version of copy(List[i],1,2)=Char1+Char2, because no temporary string is created during the comparison. But it works only if no List[i]='', i.e. no pointer(List[i])=nil.

I've added a {$ifdef UNICODE} and sizeof(char) in order to have this code compile with all version of Delphi (before and after Delphi 2009).

like image 154
Arnaud Bouchez Avatar answered Jan 02 '23 12:01

Arnaud Bouchez


To stop running a loop, use the break command. Exit is also useful to leave an entire function, especially when you have multiple nested loops to escape. As a last resort, you can use goto to jump out of several nested loops and continue running in the same function.

If you use a while or repeat loop instead of a for loop, the you can include another conjunct in your stopping condition that you set mid-loop:

i := 0;
found := False;
while (i < count) and not found do begin
    // search for items
    found := True;
    // more stuff
    Inc(i);
end;
like image 30
Rob Kennedy Avatar answered Jan 02 '23 14:01

Rob Kennedy