Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Бегание по иерархической структуре. / 18 сообщений из 18, страница 1 из 1
16.01.2006, 17:17
    #33485578
Бегание по иерархической структуре.
Всех с праздниками!

Посоветуйте хороший, читабельный код для бегания по дереву.

Вот структура файла:
ParentID , KeyID , Map



За ранее спасибо )
...
Рейтинг: 0 / 0
16.01.2006, 18:05
    #33485703
Urri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Люблю рекурсии в данном аспекте.
...
Рейтинг: 0 / 0
17.01.2006, 08:23
    #33486220
Андрей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
UrriЛюблю рекурсии в данном аспекте.
Хорошая мысль - но как рекурсия реализована в FoxPro?
...
Рейтинг: 0 / 0
17.01.2006, 09:59
    #33486424
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
А я использую для этих целей стек. Такой структуре нет в VFP, поэтому пришлось создать класс на основе Custom, который имеет три метода:
PUSH - положить на верхушку стека
POP - снять с верхушки стека
GetNumRecord - вернуть кол-во записей с стеке.
Если интересно, могу привести код.
С уважением, Алексей
...
Рейтинг: 0 / 0
17.01.2006, 10:08
    #33486448
Urri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Процедурно. ;-)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
do x with 'c:\'

proc x
lparam pcurpath
local i
if type('spc')!='C'
  private spc
  spc = ''
endif
=adir(xzx,pcurpath+'*.*','D')
for i =  1  to alen(xzx, 1 )
  if left(xzx(i, 1 ), 1 ) != '.'
    ? pcurpath+xzx(i, 1 )
    spc = spc + '  '
    do x with pcurpath+xzx(i, 1 )+'\'
    spc = left(spc,len(spc)- 2 )
  endif
next

(Пишу набело, поэтому код скорее всего работать как есть не будет ;-))
...
Рейтинг: 0 / 0
17.01.2006, 10:12
    #33486463
Urri
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Aleksey-K, конечно, с удовольствием посмотрим!
...
Рейтинг: 0 / 0
17.01.2006, 12:36
    #33486899
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Класс Steck
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
DEFINE CLASS Steck AS Custom
	Stack_Rec =  0 
	DIMENSION Stack[ 1 ]

PROCEDURE Init
	DIMENSION THIS.Stack[ 1 ]
	THIS.Stack_Rec =  0 
ENDPROC

PROCEDURE getnumrecord
	RETURN THIS.Stack_Rec
ENDPROC

PROCEDURE push
	LPARAMETERS lnID
	*-- Помещение на верхушку стэка
	THIS.Stack_Rec = THIS.Stack_Rec +  1 
	DIMENSION THIS.Stack[THIS.Stack_Rec]
	THIS.Stack[THIS.Stack_Rec] = m.lnID
ENDPROC

PROCEDURE pop
	*-- Снимаем с верхушки стэка значение с удалением его из стэка и дикрементом указателя
	LOCAL lRet
	IF THIS.Stack_Rec =  0 
		RETURN  0 
	ENDIF
	m.lRet = THIS.Stack[THIS.Stack_Rec]
	THIS.Stack_Rec = THIS.Stack_Rec -  1 
	RETURN (m.lRet)
ENDPROC
ENDDEFINE

А так можно, например, его использовать:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
*-- Таблица TreeTabl имеет, как минимум, поля ParentID , KeyID
*--ЗАДАЧА: Найти все KeyID, который подчиняются lnKeyID и записать их
*-- в курсор Result
USE IN SELECT("Result")
CREATE CURSOR Result (KeyID I)
loSteck = CREATEOBJECT("Steck")
loSteck.Push(m.lnKeyID)
*-- Главнй цикл
DO WHILE loSteck.GetNumRecord() >  0 
	*-- Снимает с верхушки стэка
	m.lnKeyID = loSteck.Pop()
	SELECT Temp 
	LOCATE FOR KeyID = m.lnKeyID 
	IF FOUND()
		SELECT Result 
		INSERT INTO Result (KeyID) VALUES (m.lnKeyID)
	ENDIF
	*-- Находим все подразделения для m.lnKeyID 
	SELECT KeyID FROM TreeTabl  INTO CURSOR temp NOFILTER ;
		WHERE ParentID = m.lnKeyID 
	*-- Переписываем их в стэк
	SELECT temp
	GOTO TOP
	SCAN
		loSteck.Push(temp.KeyID)
	ENDSCAN
	USE IN SELECT("temp")
ENDDO
RELEASE loSteck
SELECT Result
GOTO TOP

С уважением, Алексей
...
Рейтинг: 0 / 0
18.01.2006, 10:41
    #33488762
Бегание по иерархической структуре.
Aleksey-K:

Спасибо, буду разбирать Ваш код )

А этот модуль можно использовать в качестве рекурсивной функции?
...
Рейтинг: 0 / 0
18.01.2006, 10:55
    #33488820
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Вы про какой модуль спрашиваете?

С уважением, Алексей
...
Рейтинг: 0 / 0
19.01.2006, 12:18
    #33491384
Бегание по иерархической структуре.
Ну, код для поиска детей в структуре, что вы написали - разве не ответ на мой вопрос ? ))

*-- Таблица TreeTabl имеет, как минимум, поля ParentID , KeyID
*--ЗАДАЧА: Найти все KeyID, который подчиняются lnKeyID и записать их
*-- в курсор Result
USE IN SELECT("Result")
CREATE CURSOR Result (KeyID I)
loSteck = CREATEOBJECT("Steck")
loSteck.Push(m.lnKeyID)
............
...
Рейтинг: 0 / 0
19.01.2006, 12:25
    #33491415
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Теперь понятно, но дело в том, что я стек и применил, что-бы не связывться с рекурсией. В некоторм роде взаимоисключающие приемы.

С уважением, Алексей
...
Рейтинг: 0 / 0
19.01.2006, 12:58
    #33491553
Андрей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Всё это работает не благодаря стеку (не в обиду сказано), а только по тому-что в FoxPro есть цикл Do While и Sql-операторы...
...
Рейтинг: 0 / 0
19.01.2006, 13:27
    #33491667
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Андрей КВсё это работает не благодаря стеку (не в обиду сказано), а только по тому-что в FoxPro есть цикл Do While и Sql-операторы...
Можно и без стека
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
LOCAL lnLevel

CREATE CURSOR  Result (KeyID I, Lev I)
m.lnLevel  =  0 
INSERT INTO Result (KeyID, Lev) ;
SELECT KeyID, m.lnLevel FROM TreeTabl WHERE KeyID = m.lnKeyID
DO WHILE _TALLY >  0 
	m.lnLevel = m.lnLevel +  1 
	INSERT INTO Result (KeyID, Lev) ;
	SELECT TreeTabl.KeyID, m.lnLevel FROM TreeTabl  ;
		INNER JOIN Result ON TreeTabl.ParentID = Result.KeyID AND Result.Lev = m.lnLevel -  1 

ENDDO

В T-SQL я тоже именно такой проход по "дереву" без стека, но получается не так красиво. Стек у меня используется и для других целей, грех было его и тут не использовать.
C Уважением, Алексей.
...
Рейтинг: 0 / 0
19.01.2006, 14:17
    #33491878
Андрей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Хороший код, Алексей.
...
Рейтинг: 0 / 0
19.01.2006, 16:35
    #33492376
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Спасибо, Андрей.
С уважением, Алексей
...
Рейтинг: 0 / 0
20.01.2006, 01:10
    #33493137
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Hi Aleksey!

> Класс Steck
> DIMENSION Stack[1]

Имя самого класса искажено намеренно? Или просто описка которая "тянется
исторически" :)

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
20.01.2006, 03:50
    #33493192
Val Kor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
** Заимствовано из книги Р. Пэддок по VFP8

** структура файла: ParentKey Cod Name

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
** структура файла: ParentKey Cod Name

** INIT объекта oletreeview1
SELECT UchD
SET ORDER TO PARENTKEY   && PARENTKEY+COD 
GO TOP 
thisform.loadfile ()

** Метод loadfile формы, где объект oletreeview1

This.oletreeview1.Nodes.Clear 
SCAN FOR ParentKey = Cod 
	This.oletreeview1.Nodes.Add(,,"KEY" + Cod, RTRIM(Name)) 
  IF SEEK(Cod)
    This.LoadNode(Cod)
  Endif    
ENDSCAN 

** Метод LoadNode формы, где объект oletreeview1
Lparameters lnKeyToLoad

*-- Save the work area
Local lnKod, lnRecno, lnRecno2
lnRecno = Recno()
Go Top
Scan For ParentKey = lnKeyToLoad
  lnKod = Cod
 If Parentkey # lnKod
    This.oletreeview1.Nodes.Add("KEY" + lnKeyToLoad, 4 ,"KEY" + lnKod, RTRIM(Name))
     lnRecno2 = Recno()
    *-- если эта запись родитель, то грузим её детей
    If Seek(lnKod)
      This.LoadNode(lnKod)
    Endif    
    *-- восстанавливаем местоположение в файле
    If lnRecno2 #  0 
     Goto lnRecno2
    Endif
 Endif
Endscan

If lnRecno #  0 
  Goto lnRecno
ENDIF

...
Рейтинг: 0 / 0
20.01.2006, 09:25
    #33493326
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Бегание по иерархической структуре.
Igor Korolyov
Hi Aleksey!

> Класс Steck
> DIMENSION Stack[1]

Имя самого класса искажено намеренно? Или просто описка которая "тянется
исторически" :)

Posted via ActualForum NNTP Server 1.3
Да, тяжелое наследие прошлого..... :)
Менять уже поздно...
С уважением, Алексей.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Бегание по иерархической структуре. / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]