Форум: "Основная";
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];
ВнизTree Walker: Create Найти похожие ветки
← →
Satirus (2002-04-19 17:14) [0]Вопрос к умудрённым опытом в использовании компонента TTreeView.
Предложите оригинальный код для перебора веток дерева снаружи внутрь. То есть, как пройтись сначала по сиблингам корня, потом по их детям, потом по сиблингам детей и т. д., до последнего колена в глубину
← →
Дмитрий Баранов (2002-04-19 17:44) [1]В цикле по всем узлам (0..TreeView1.Items.Count-1) строим массив массивов (динамических) указателей (TTreeNode).
Первый индекс - Items[i].Level, второй - порядковый номер узла в массиве.
Вариации на тему - не массивы, а стеки (динамический массив - тормоз).
Выстроили - работаем.
← →
vuk (2002-04-19 17:45) [2]Рекурсивно. То есть пишется процедура, поторой на вход подается узел и она сначала проходит по всем его дочерним узлам а потом делает второй проход по ним же и вызывает сама себя, передавая каждый из дочерних узлов в качестве параметра.
← →
vuk (2002-04-19 17:46) [3]Рекурсивно. То есть пишется процедура, которой на вход подается узел и она сначала проходит по всем его дочерним узлам а потом делает второй проход по ним же и вызывает сама себя, передавая каждый из дочерних узлов в качестве параметра.
← →
MBo (2002-04-19 17:48) [4]если не хранить номера узлов, имеющих деток, то придется обходить все, проверяя level, т.е. сначала с level 0, потом с 1 ,и т.д., пока не будет таких 0.
А можно создавать при первом обходе список, сортированный по level и дальше по нему.
← →
vuk (2002-04-19 17:55) [5]А чем рекурсия не устраивает?
← →
Satirus (2002-04-19 17:58) [6]Дмитрий Баранов-> можно по подробней? Идея динамического массива у меня возникла сразу... Развейте её, пожалуйста, в виде кода
← →
Дмитрий Баранов (2002-04-19 18:10) [7]Вот с удовольствием бы, только времени нет. Динамический массив как он реализован в Delphi я бы применять не стал, а взял бы аналог С++ map. В Delphi придется извращаться -
Type TArrNode = array of TTreeNode;
Type TTree = array of TArrNode;
(с array of array шибко нечитаемый код получается),
а затем везде впихивать SetLength.
Если это не очень срочно, то могу на выходных подумать.
← →
vuk (2002-04-19 18:12) [8]Понял свою лажу. Извиняюсь.
← →
Satirus (2002-04-19 18:17) [9]vuk-> Меня устраивает рекурсия, но я не знаю, с какой стороны к ней подойти. Можно примерный кусочек кода?
Заранее благодарен
← →
Дмитрий Баранов (2002-04-19 18:24) [10]На коленках - рекурсия.
procedure Recurse(const Node: TTreeNode);
var i: integer;
begin
ShowMessage(Node.Text);
if not Node.HasChildren then exit
else
begin
for i:=0 to Node.Count-1 do
begin
Recurse(Node.Item[i]);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var Node: TTreeNode;
begin
Node:=TreeView1.Items[0];
Recurse(Node);
end;
← →
MBo (2002-04-19 18:25) [11]procedure TForm1.Button1Click(Sender: TObject);
var sl,sl2:TStringlist;
i,j,k:integer;
begin
sl:=tstringlist.create;
sl2:=tstringlist.create;
for i:=0 to tv1.Items.count-1 do begin
j:=tv1.items[i].level-sl.count+1;
if j>0 then
for k:=1 to j do sl.add("");
sl[tv1.items[i].Level]:=sl[tv1.items[i].Level]+inttostr(i)+" ";
end;
for i:=0 to sl.count-1 do begin
memo1.lines.add("Level "+inttostr(i));
sl2.commatext:=sl[i];
for j:=0 to sl2.count-1 do
memo1.lines.add(tv1.items[strtoint(sl2[j])].text);
end;
sl.free;
sl2.free;
end;
← →
Дмитрий Баранов (2002-04-19 18:30) [12]>> MBo © (19.04.02 18:25)
Тоже на коленках :) ?
Меня, например удивляет, почему в Delphi встроеных хэшей и мапов нет :)) StringList - это не выход :)) Это слишком просто и медленно :))
← →
vuk (2002-04-19 18:32) [13]Рекурсия не пойдет. Я немного не верно понял задачу. Нормальным решением рекурсия будет только тогда, когда нужен проход в таком порядке: сначала корень, потом его первый дочерний узел, и т.д. в глубь, т.е. каждая ветка проходится до конца перед тем как будет пройдена другая ветка. У Вас же условие другое - перебор должен идти по уровням, а не по веткам.
← →
Satirus (2002-04-19 18:56) [14]vuk-> Ну да. Мне надо пройтись по уровням
← →
MBo (2002-04-19 19:22) [15]>StringList - это не выход :))
это демонстрация подхода, но вполне рабочий вариант
>Это слишком просто и медленно :))
все зависит от диаметры иглы - количества items
← →
Satirus (2002-04-19 21:01) [16]>>vuk Возвращаясь к вопросу использования библиотеки XDOM, хочу спросить Вас, не использовали ли Вы её встроенный TDOMTreeWalker, подобие которого я и пытаюсь создать, но в облегченном варианте. Целевым объектом триволкера является всё тот же XML-file, но вот незадача, не могу его побороть! Может у Вас найдется пару простеньких примерчиков по вытягиванию древа из XML-file?
Буду очень признателен.
← →
vuk (2002-04-19 21:10) [17]Дерево-то проще всего вытягивать рекурсивно, а не по уровням. Все достаточно прозрачно получается. В составе XDOM даже пример имеется как это сделать.
имя файла:
\example03\example03main.pas
Метод:
procedure TMainpage.UpdateTreeView(const doc: TdomDocument);
← →
Satirus (2002-04-19 21:32) [18]>>vuk Этот пример я разбирал первым делом. Но там один недостаток: ветки названы по типу, а не по имени элемента, к тому же сложно вытянуть атрибуты каждой ветки...
← →
vuk (2002-04-19 21:38) [19]Ну и какие проблемы? Переписать создание узлов - и все дела. А как атрибуты вытягивать - я Вам уже писал.
← →
Набережных С. (2002-04-19 22:43) [20]Пример с массивом:
type
TArr = array of array of TTreeNode;
procedure Parse(TV: TTreeView; var A: TArr);
var
n,m,k:integer;
begin
m:=0; n:=0;
while n < TV.Items.Count do
with TV.Items[n] do
begin
if Level >= m then
begin
m:=Level + 1;
SetLength(A,m);
end;
k:=Length(A[Level]);
SetLength(A[Level],k+1);
A[level,k]:=TV.Items[n];
Inc(n);
end;
end;
Пример вызова:
var
Arr:TArr;
Parse(TreeView1,Arr);
for n:= 0 to Pred(Length(Arr)) do
begin
for m:=0 to Pred(Length(Arr[n]))do
Memo1.Lines.Add(StringOfChar(" ",Arr[n,m].Level*4)+Arr[n,m].Text);
end;
← →
Satirus (2002-04-20 19:05) [21]>>Набережных С. Ваш пример выдает ошибку Undeclared identifier "Items"
← →
Набережных С. (2002-04-20 19:29) [22]
> Satirus © (20.04.02 19:05)
У меня на D5 не выдает. Возможно, в D6 изменили TTreeView, но тут я помочь не смогу. А ты никаких изменений не вносил? Покажи на всякий случай свой код.
← →
Satirus (2002-04-20 20:04) [23]>>Набережных С. Я его отправил Вам на мыло
← →
Набережных С. (2002-04-20 20:43) [24]Письмо получил. Дело в том, что строка
Nodes[level,ChildCount]:=TreeView.Items[NodeCount];
стоит внутри блока with и у TTreeNode есть свойство TreeView: TCustomTreeView, а у TCustomTreeView свойство Items не опубликовано. Измени имя параметра TreeView и все будет нормально.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.006 c