首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较2个LISTBOX

比较2个LISTBOX
EN

Stack Overflow用户
提问于 2020-09-27 01:41:24
回答 2查看 110关注 0票数 0

我在Win 64 sp2上运行D7企业版。

在我的程序中,我有两个列表框(lb1,Lb2)。

Lb1最多可包含35.000个项目。(string4 ) Lb2最多可包含35.000个项目。(string4 )

这两个列表框都已排序。

在列表框中可能有重复的项(从0到30.000 ),我想找到这些重复项。

我已经尝试了“自下而上”类型(例如:从listbox2的底部获取元素,扫描listbox1到底部,标记相等的元素,(最终复制到第三个列表框),再次获取下一个元素I listbox2 do sacn I lisbox1,并继续到顶部f Listbox2。)

这种方法确实有效,但它很繁琐,而且非常慢(大约需要。8分钟(+/-) / 35000个项目LB1 / 25000个项目LB2)。

我想知道是否可以将TStringList组件: TStringList.NoDuplicates;修改为

TStringList.getDuplicates;或者类似的东西,如果有,我该怎么做??

或者我没有在TStringList组件中发现一个“隐藏的”可能性/方法(至少对我来说是这样)?

还是有第三种方法可以找到副本?

请帮帮忙。

谢谢

克里斯

EN

回答 2

Stack Overflow用户

发布于 2020-09-27 20:39:50

这是一个好主意,就像你亲手做的那样,用你的手指沿着每个列表往下看。

以下是完成此操作的过程。

代码语言:javascript
复制
procedure TFormTest.CompareLists(const Lista, Listb, Listc: TStrings);
var
  a, b, amax, bmax : integer;
begin
  aMax := Lista.Count;
  bMax := Listb.Count;

  Listc.Clear;

  a:=0;
  b:=0;

  while (a< aMax) and (b<bMax) do
  begin
    // Once either index goes past end of list we are done;
    case Sign( CompareStr( Lista[a], Listb[b])) of  // oer CompareText if not case sensitive
      -1:
      begin
        // ista[a] < List0[ b ]b
        inc( a );
      end;
      0:
      begin
        // a = b
        Listc.add( Lista[a] );  // same so could be either
        inc(a);
        inc(b);
      end;
      1:
      begin
        inc( b );
      end;
    end;
  end;
end;

你可以直接把它复制到你的程序中。

它还可以很容易地比较复制到外部列表是否值得。我这样做了,发现使用列表框条目大约需要4秒,对于35000个条目(比4个字符长得多),对于单独的列表,使用列表框条目需要不到1秒。这种差异远远超过了将项目复制到单独的字符串列表所需的时间,但这两种时间都比您所实现的要好得多。

下面是完整的测试单元:

代码语言:javascript
复制
unit UnitTest;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Math, Vcl.StdCtrls;

type
  TFormTest = class(TForm)
    ListBox1: TListBox;
    ListBox2: TListBox;
    ListBox3: TListBox;
    EditCompareLists: TEdit;
    EditCompareListBoxes: TEdit;
    ButtonTest: TButton;
    EditCount1: TEdit;
    EditCount2: TEdit;
    EditCount3: TEdit;
    procedure ButtonTestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CompareLists( const Lista, Listb, Listc : TStrings );
  end;

var
  FormTest: TFormTest;

implementation

{$R *.dfm}

{ TForm1 }

procedure TFormTest.ButtonTestClick(Sender: TObject);
var
  List1, List2, List3 : TStringList;
  iTime : TTime;
  i: Integer;
begin
  // 1. Generate lists - should be string[4] but if bigger should slow things down
  List1 := TStringList.Create;
  Try
    List2 := TStringList.Create;
    try
      List3 := TStringList.Create;
      try
        List1.Sorted := TRUE;
        List2.Sorted := TRUE;
        List1.Duplicates := dupIgnore;
        List2.Duplicates := dupIgnore;

        for i := 1 to 50000 do
        begin
          List1.Add( IntToStr( Random( 65000 )));
          List2.Add( IntToStr( Random( 65000 )));
        end;

        ListBox1.Items.Assign( List1 );
        ListBox2.Items.Assign( List2 );

        EditCount1.Text := IntToStr(ListBox1.Items.Count );
        EditCount2.Text := IntToStr(ListBox2.Items.Count );
        // now see how fast eachcan be sorted
        // first - list boxes
        iTime := Now;
        CompareLists( ListBox1.Items, ListBox2.Items, ListBox3.Items );
        iTime := Now - iTime;
        EditCompareListBoxes.Text := TimeToStr( iTime );
        EditCount3.Text := IntToStr(ListBox3.Items.Count );

        // and Lists
        iTime := Now;
        CompareLists( List1, List2, List3 );
        iTime := Now - iTime;
        EditCompareLists.Text := TimeToStr( iTime );
      finally
        List3.Free;
      end;
    finally
      List2.Free;
    end;
  Finally
    List1.Free;
  End;
end;

procedure TFormTest.CompareLists(const Lista, Listb, Listc: TStrings);
var
  a, b, amax, bmax : integer;
begin
  aMax := Lista.Count;
  bMax := Listb.Count;

  Listc.Clear;

  a:=0;
  b:=0;

  while (a< aMax) and (b<bMax) do
  begin
    // Once either index goes past end of list we are done;
    case Sign( CompareStr( Lista[a], Listb[b])) of  // oer CompareText if not case sensitive
      -1:
      begin
        // ista[a] < List0[ b ]b
        inc( a );
      end;
      0:
      begin
        // a = b
        Listc.add( Lista[a] );  // same so could be either
        inc(a);
        inc(b);
      end;
      1:
      begin
        inc( b );
      end;
    end;
  end;
end;

end.
票数 2
EN

Stack Overflow用户

发布于 2020-09-27 17:18:06

要比较两个排序的列表,您可以比较第一个条目,然后根据比较结果前进一个或两个列表:

  • 等于:复制,在两个列表上前进到下一个列表
  • first> than second,前进到第二个列表上的下一个list
  • second > first,前进到第一个列表上的下一个list
  • 一个或两个列表end : done

正如其他人提到的,在列表控件中比较数据将比在字符串列表或数组之间慢得多。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64080775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档