Board index » delphi » ListBox question

ListBox question

Hello-

Here is my problem: I have a FileListBox and a regular ListBox. I also
have a button that will copy all of the filenames from the FileListBox
into the other ListBox, if they are not already there...

{-------------------------}

procedure TForm1.ChooseAllButtonClick(Sender: TObject);
var
   I, J : integer;
   AlreadyThere : boolean;
begin
   for I := 0 to (FileListBox1.Items.Count - 1) do
   begin
     AlreadyThere := false;
     for J := 0 to (ListBox1.Items.Count - 1) do
       if ListBox1.Items [J] = FileListBox1.Items [I] then
         AlreadyThere := true;
     if not AlreadyThere then
       ListBox1.Items.Add(FileListBox1.Items [I]);
   end;
end;

{-------------------------}

This works but is VERY slow, as it must do many comparisons if either
of the lists is very long.  Can anyone think of a faster way to
accomplish this? Please reply by e-mail.

Thanks.

-MJ
jenni...@jmu.edu

 

Re:ListBox question


Quote
MJ wrote:

> Hello-

> Here is my problem: I have a FileListBox and a regular ListBox. I also
> have a button that will copy all of the filenames from the FileListBox
> into the other ListBox, if they are not already there...

> {-------------------------}

> procedure TForm1.ChooseAllButtonClick(Sender: TObject);
> var
>    I, J : integer;
>    AlreadyThere : boolean;
> begin
>    for I := 0 to (FileListBox1.Items.Count - 1) do
>    begin
>      AlreadyThere := false;
>      for J := 0 to (ListBox1.Items.Count - 1) do
>        if ListBox1.Items [J] = FileListBox1.Items [I] then
>          AlreadyThere := true;
>      if not AlreadyThere then
>        ListBox1.Items.Add(FileListBox1.Items [I]);
>    end;
> end;

> {-------------------------}

> This works but is VERY slow, as it must do many comparisons if either
> of the lists is very long.  Can anyone think of a faster way to
> accomplish this? Please reply by e-mail.

> Thanks.

> -MJ
> jenni...@jmu.edu

procedure TForm1.ChooseAllButtonClick(Sender: TObject);
var
 I, J : integer;
 AlreadyThere : boolean;
begin
 for I := 0 to (FileListBox1.Items.Count - 1) do
 begin
  if ListBox1.Indexof(FileListBox1.Items[i] = -1 then
   ListBox1.Items.Add(FileListBox1.Items [I]);
  end;
 end;

Try this piece of code. The TListBox has a method IndexOf(STRING) that
either returns the location (index) of the string you sent within the
listbox. If the string is not there, it returns - 1. What the method
does is check the list box for the string (same as your program above).
I beleive it is a bit faster but not sure. Never tried it on large
lists. Otherwise you have to look into using a string matching search
algorithm. (Like the ones used to search a document for some text)

Good luck..

jrp0...@jove.unt.edu

 -------------==== Posted via Sexzilla News ====------------------
    http://www.sexzilla.com        Search, Read, Post to Usenet
 -------------====   With A Whole Lot More  ====------------------

Re:ListBox question


Quote
> procedure TForm1.ChooseAllButtonClick(Sender: TObject);
> var
>    I, J : integer;
>    AlreadyThere : boolean;
> begin
>    for I := 0 to (FileListBox1.Items.Count - 1) do
>    begin
>      AlreadyThere := false;
>      for J := 0 to (ListBox1.Items.Count - 1) do
>        if ListBox1.Items [J] = FileListBox1.Items [I] then
>          AlreadyThere := true;
>      if not AlreadyThere then
>        ListBox1.Items.Add(FileListBox1.Items [I]);
>    end;
> end;

> {-------------------------}

Yeah, that is REALLY slow.  If FileListBox1.Items.Count = N, then this
runs in time proportional to N^2.  Why don't you sort ListBox1 and then
do a binary search on it?  Failing to find the item from FileListBox1
using a binary search will then lead directly to where it should be
inserted into the ListBox1!  This will bring your running time down to
N*(log_2 N), which should be noticeably faster.  (I hope you can sort a
listbox and add items to a specific index in a listbox.  I can't
remember right now.)

What would be even better would be to sort BOTH lists (and again, I'm
not sure of your sorting options for ListBoxes and FileListBoxes).
Traverse both of them at the same time.  Starting with both I and J
equal to 0, advance "I" until you've found a match at ListBox1.Items[J]
(in which case increment both I and J) or until you're alphabetically
past what's in FileListBox1.Items[I] (in which case, add the item to the
ListBox, as it's obvious that, since you passed where it would be in a
sorted array, but didn't find it, it's not there.)  This will run in
time proportional to N, and that's theoretically as fast as you can do
it!

nate

Other Threads