Delphi VirtualStringTree - проверка на наличие дубликатов? - PullRequest
2 голосов
/ 15 января 2011

Да, я знаю, что я публикую много вопросов, но это потому, что мне либо нужна уверенность в том, что я делаю это правильно, что я делаю неправильно, либо, если я совершенно не в курсе, и не могу найти ничего в документации.В любом случае,

Я пытаюсь проверить наличие дублирующих узлов.Вот как я бы хотел это сделать:

Зацикливать мои узлы и сравнивать текст (запись) каждого отдельного узла, но если бы я получил много узлов, разве это не было бы слишком много времени и памяти?Будет ли лучший подход для этого?

Спасибо!- Джефф.

РЕДАКТИРОВАТЬ: Благодаря Deltics, я получил это работает!Если у нас есть люди с таким же вопросом, вот рабочий код, использующий 2 уровня узлов в VST!

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;

Я не боюсь делиться своим кодом, я в долгу перед сообществом.:)

Ответы [ 3 ]

1 голос
/ 15 января 2011

версия Дэвида будет работать.Если у вас D2010 или новее, вы также можете использовать коллекцию Set из DeHL, которая использует хэш для проверки на наличие дубликатов и может обработать ваш список за O (n) раз.

1 голос
/ 15 января 2011

Зависит от того, в какой момент вы проверяете наличие дубликатов.

Если это в тот момент, когда вы добавляете элементы и добавляете все элементы одновременно (или если возможно / целесообразно переместить дубликат проверки в точку, в которой заполняется древовидное представление, а не работа с уже заполненным деревом), то самым простым способом может быть ведение списка уже добавленных элементов, например при условии, что вы добавляете элементы из простого списка строк (в строках в этом коде иллюстрации):

  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;
1 голос
/ 15 января 2011

Обычно вы собираете все свои строки в список, а затем сортируете его.Затем вы можете просмотреть и проверить соседние элементы на равенство.

Это O (n log n), предполагая разумный алгоритм сортировки, а не простой алгоритм O (n ^ 2).Если у вас нет множества предметов, тогда наивный будет отлично работать.

...