Рекурсия [Юрий Карпов] (fb2) читать постранично, страница - 1
[Настройки текста] [Cбросить фильтры]
Рекурсия
|t_| Доброго времени суток!|go| Готов с вниманием внимать, все то, что ты, zz сказать. (переменная zz пока не определена).
|t_| Давай присвоим zz := 'хотел'. Напомню, сегодня, наша тема - рекурсия.
|go| Я посмотрел, что говорит на эту тему википедия - что-то уж очень закручено... но вообще-то мы такое проходили... Фотография: мужик смотрит на фотографию на ней он же смотрит на туже фотографию, на ней...
|t_| Уже легче. Давай использовать облегченное определение. Рекурсия, это когда внутри процедуры (функции) есть вызов ее самой:
procedure МояПроцедура(параметры); begin ... что-то там делается ... if условие потребности в рекурсии then МояПроцедура(параметры); ... и еще что ни будь сделаем ... end;
Условие потребности в рекурсии, рано или поздно должно стать false иначе она станет бесконечной и программа зависнет. Возможен и такой вариант:
function МояФункция(параметры):boolean; begin ... что-то там делается ... if МояФункция(параметры) then exit; ... result := условие выхода из рекурсии ... end; Конечно же, возможны сотни других вариантов... Надеюсь, что не очень напряг тебя теорией, теперь к практике.
|go| Да нет, все нормально. Поехали. :( Yes no, all OK. Let's go. :)
|t_| Сегодня у тебя поэтическое настроение, это хорошо... Рекурсия очень хорошо подходит для обхода дерева, например дерева файловой системы.
Задача. Написать программку удаляющую все пустые папки в заданной папке ( устройстве ). (готовый исходник можно извлечь из этой книги, и имя его del_empty_dir.zip1 ) Давай сделаем простенькую форму с одной только кнопочкой. При нажатии должен появляться диалог выбора папки, и после этого просмотрим все входящие папки и удалим пустые. Да еще, посчитаем удаленные и сообщим результат.
|go| Ну, что делаем новый проект в новой папке?
|t_| Да, как всегда. На форме одну кнопочку, и вот обработчик ее клика и все остальное. Давай, попробуй выполнить программку, создай пустую папку и попробуй ее удалить. А потом обсудим. // начало кода { 0 } var { 1 } Form1: TForm1; { 2 } Path : AnsiString; // путь к папке с программой { 3 } count : integer; // счетчик удалений { 4 } { 5 } implementation { 6 } { 7 } {$R *.dfm} { 8 } { 9 } function DelEmtyDir(Target : AnsiString):boolean; { 10 } var { 11 } Found : integer; // результат поиска ( 0 - файл найден ) { 12 } SR : TSearchRec; // запись с параметрами файла { 13 } begin { 14 } Found := FindFirst(Target + '\*.*',$3F,SR); { 15 } result := true; // предположим что папка пуста. { 16 } WHILE Found = 0 DO { 17 } BEGIN { 18 } if (SR.Name <> '.') { 19 } and (SR.Name <> '..') { 20 } then { 21 } begin { 22 } // если это папка { 23 } if ((SR.Attr and $10) = $10 ) then { 24 } begin // рекурсивный вызов функции { 25 } if DelEmtyDir( Target+'\'+ SR.Name) { 26 } then { 27 } begin // удаление пустой папки { 28 } RmDir(Target+'\'+ SR.Name); { 29 } inc(count); // + 1 в счетчик { 30 } end; { 31 } end { 32 } else { 33 } begin // найден какой то файл { 34 } result := false; // значит папка не пуста. { 35 } FindClose(SR); { 36 } exit; { 37 } end; { 38 } end; { 39 } Found := FindNext(SR); { 40 } END;{DosError = 0} { 41 } FindClose(SR); { 42 } end; { 43 } { 44 } procedure TForm1.Button1Click(Sender: TObject); { 45 } var { 46 } Dir : AnsiString; { 47 } begin { 48 } Dir := Path; count := 0; { 49 } if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt],0) { 50 } then { 51 } begin { 52 } if Dir[length(Dir)]='\' { 53 } then delete(Dir, length(Dir),1); { 54 } DelEmtyDir(Dir); { 55 } ShowMessage('Deleted ' + IntToStr(count) +' folders.'); { 56 } end; { 57 } end; { 58 } { 59 } procedure TForm1.FormCreate(Sender: TObject); { 60 } begin { 61 } Path := ExtractFileDir(ParamStr(0)) + '\'; { 62 } end; // конец кода
|go| Не работает. Delphi не знает кто такое SelectDirectory.
|t_| Ничего, потихоньку научишься работать, поставь курсор на слово - ошибку и нажми F1.
|go| Получил help. Ну и что дальше.
|t_| В help найди к какому unit относился функция SelectDirectory и вставь это название в uses своей программы. Так поступай и в дальнейшем, больше старайся использовать help и умеренно, советы из интернета, к сожалению в этой "всемирной свалке" надо хорошо покопаться чтобы найти алмазы, а по пути можно и замазаться...
|go| Как сказал кот Матроскин - "Заработало!!!"
|t_| Хорошо, ну а теперь найди в программе ошибку. Подсказка, тоже цитата "Хотели как лучше, а получилось... "
|go| Нашел, каждый раз при нажатии кнопки выбор папки начинается из папки программы, а это неудобно.
|t_| Ну, ты даешь! Нашел не запланированную мною ошибку. Ты совершенно прав. Давай исправлять. { 46 } Dir : AnsiString; - определение переменной сделай глобальным
{ 0 } var { 1 } Form1: TForm1; Dir : AnsiString; { 2 } Path : AnsiString; // путь к папке с программой
а строчку 46 удали теперь: { 48 } Dir := Path; - это присваивание отсюда забери и вставь в:
{ 61 } Path := ExtractFileDir(ParamStr(0)) + '\'; Dir := Path; { 62 } end; Ну, а теперь, ищи дальше.
|go| Не понял смысла в строках { 52 } if Dir[length(Dir)]='\' { 53 } then delete(Dir, length(Dir),1); Dir и так возвращается без конечного слеша.
|t_| Не совсем так. Если ты будешь искать в корневом каталоге, то там будет слеш (например: с:\ ). Ищи дальше.
|go| Наверно это строки { 33 } begin // найден какой то файл { 34 } result := false; // значит папка не
Последние комментарии
11 часов 22 минут назад
11 часов 41 минут назад
11 часов 49 минут назад
11 часов 51 минут назад
11 часов 53 минут назад
12 часов 11 минут назад