Рекурсия [Юрий Карпов] (fb2) читать постранично
[Настройки текста] [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; // значит папка не
Последние комментарии
2 часов 31 минут назад
2 часов 51 минут назад
3 часов 17 минут назад
3 часов 20 минут назад
12 часов 51 минут назад
12 часов 54 минут назад