【问题标题】:Delphi VirtualStringTree - Check for Duplicates?Delphi VirtualStringTree - 检查重复项?
【发布时间】:2011-01-14 23:10:11
【问题描述】:

是的,我知道我发布了很多问题,但那是因为我需要保证我做对了,我做错了什么,或者我完全一无所知,并且在文档中找不到任何内容。总之,

我正在尝试检查重复节点。这是我想做的事情:

循环遍历我的节点,并比较每个节点的文本(记录),但是如果我有很多节点,那会不会太耗时和消耗内存?会有更好的方法吗?

谢谢! - 杰夫。

编辑:感谢 Deltics,我得到了它的工作!如果我们有一些人有同样的问题,这里有一些工作代码,在 VST 中使用 2 级节点!

Procedure UncheckDuplicates;
Var
 ParentNode,ChildNode : PVirtualNode;
 I,J                  : Integer;
 SL                   : TStringList;
 SkypeID              : String;
Begin

   SL := TStringlist.Create;
   try
        ParentNode                      := frmMain.vtSkype.GetFirst;

           for I := 0 to frmMain.vtSkype.RootNodeCount - 1 do
             begin
               ChildNode                := ParentNode.FirstChild;
                 for J := 0 to ParentNode.ChildCount - 1 do
                     begin
                        if NodeIsChecked(ChildNode) then
                          begin
                            SkypeID             := GetData(ChildNode).SkypeID;
                              if SL.IndexOf(SkypeID) <> -1 then
                                begin
                                  ChildNode.CheckState          := csUncheckedNormal;
                                end
                                else 
                                begin
                                  SL.Add(SkypeID);
                                end;
                          end;                          
                     ChildNode                := ChildNode.NextSibling;   
                     end;


               ParentNode               := ParentNode.NextSibling;
             end;


   finally
     SL.Free;
   end;

frmMain.vtSkype.Refresh;


End;

我不怕分享我的代码,这是我对社区的责任。 :)

【问题讨论】:

  • 如果您正在检查节点的文本,那么您做错了。在您的基础数据结构中查找重复项。一旦您消除了那里的重复项,然后设置RootNodeCountChildCount 以使控件为您的所有项目创建节点。树控件不应该是您存储程序数据的位置。这只是数据的视图
  • @Rob - 是的,但说文本更容易。我像其他人一样将我的东西存储在记录中;)
  • 根据您的代码,您将内容存储在树视图控件中。这个想法是您应该拥有一个完全独立的数据结构,您可以在不依赖于树控件的情况下对其进行操作和探索。您根本不必引用PVirtualNode。 (除此之外,您应该真正使用GetNextSibling 方法,而不是直接读取NextSibling 字段;该方法可确保您获得的节点已正确初始化。)
  • @Rob - 我不确定我会怎么做。显示的方式就是我被教导的方式。
  • @Rob @Jeff Rob 是对的,但以“正确”的方式进行操作更复杂。当你需要在没有任何 UI 的情况下使用你的模型时,即没有树视图,那么你就会明白为什么 Rob 会这样说。但在那之前,我认为你不必担心太多。

标签: delphi duplicates virtualtreeview


【解决方案1】:

这取决于您检查重复项的时间。

如果它是在您添加项目的点并且您同时添加所有项目,(或者如果可能/适合将您重复检查移动到填充树视图的点,而不是使用已经填充的树)然后随时维护已添加项目的列表可能是最简单的方法,例如假设您正在从一个简单的字符串列表中添加项目(在此插图代码中的 strings 中):

  alreadyAdded := TStringList.Create;
  try
    alreadyAdded.Sorted := TRUE;  // Sorting ensures an efficient binary lookup for IndexOf()...

    for i := 0 to Pred(strings.count) do
    begin
      if alreadyAdded.IndexOf(strings[i]) <> -1 then
        CONTINUE;

      AddNode(strings[i]);
      alreadyAdded.Add(strings[i]);
    end;
  finally
    alreadyAdded.Free;
  end;

【讨论】:

  • 根据这个例子写了一些工作代码,谢谢,就像一个魅力!我怎么没想到?! :P
【解决方案2】:

通常,您会将所有字符串收集到一个列表中,然后对其进行排序。然后,您可以循环并检查相邻项目是否相等。

假设一个合理的排序算法是 O(n log n),而不是 O(n^2) 的朴素算法。如果你没有大量的项目,那么天真的会很好地工作。

【讨论】:

  • @deltics 我认为基于以前的问题没有太多的层次结构。你会怎么做?
  • 查看我的答案 - 决定我对您的评论的评论没有太大帮助。我没有看过“以前的问题”(可能来自同一张海报?),但仅凭这个问题的力量,涉及树视图而不是列表框或列表视图等的简单事实强烈表明存在层次结构.
  • @Deltics - 我只使用 VT 来提高速度。但是是的,有 2 级节点(0 和 1)
【解决方案3】:

David 的版本可以使用。如果您有 D2010 或更高版本,您还可以使用 DeHL 的 Set 集合,它使用哈希来检查重复项,并且可以在 O(n) 时间内处理您的列表。

【讨论】:

  • 甚至是新推出的独立收藏
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多