Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Shpora_po_programmirovaniyu_k_ekzamenu_33_1.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
573.95 Кб
Скачать

Билет 37. Рекурсия и итерация.

Итерация (Пример):

Вычислить факториал: I: =0; F: =1;

While I<n do Begin Inc(i); inc(f) End;

Пример 2. Вычисление чисел Фибаначи определяется следующим соотношением:

Fib (n+1)=Fib(n)+fib(n-1) N>0

Fib(1)=1; Fib(0)=0

Лобовой подход:

Function (Fibin:integer):integer;

Begin If n =0 then fib:=0 Else If n=1 then Fib:=1 Else Fib:= fib(n-1) +Fib(n-2) End.

Каждое обращение при n=1 приводит к 2-м дальнейшим обращениям, для N=5 получается 15 вызовов, поэтому здесь надо придумать итеративную форму:

I=1; x:=1; y:=0;

While I<n do Begin Z:=x; I:=I+1 X:=x + y; y:=z Это равнозначно: X:=x + y Y:=x – y End;

Вывод: Следует избегать рекурсий, когда имеется очевидное итеративное решение поставленной задачи. Во многих случаях она вполне приемлема. Программы, использующие рекурсивные процедуры отличаются простотой и наглядностью. Такие качества рекурсивных алгоритмов вытекают из того, что рекурсивные процедуры указывают, что нужно делать, а не рекурсивные, как нужно делать. Для практических целей каждой рекурсивную процедуру можно преобразовать в итеративную, но часто эти преобразования до такой степени заслоняют суть программы, что понять её становится слишком сложно. В таких случаях следует использовать рекурсию.

Билет 38. Линейный поиск.

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

Условие окончания:

· Элемент найден, т.е. а[i]=х.

· Весь массив просмотрен, а элемента не обнаружено.

While (i<n) and (a[i]<>x) do i:=i+1;

Инвариант цикла, т.е. условие, выполняющееся перед каждым увеличением индекса i: (0≤i<n) and (k: 0≤k<i; a[k]≠x).

Условие окончания: ((i=n) or (a[i]=x)) and (k: 0≤k<i; a[k]≠x).

Это условие не только указывает на желаемый результат, но и также оно говорит, что элемент найден с минимальным значением индекса.

Равенство i=n свидетельствует о том, что совпадения не было. Очевидно, что окончания цикла гарантировано и за конечное число шагов мы можем достичь предела n.

Билет 39. Поиск делением пополам.

Если нам известна дополнительная информация о данных, например, что они упорядочены, то поиск можно сделать более эффективным.

Основная идея: выбрать случайные элементы a[m] и сравнить с аргументом поиска х, если он равен х, то конец поиска, если меньше х, то все элементы с индексами меньше или равно m можно исключить из рассмотрения, если же он больше х, то исключаются элементы с индексом больше или равно m.

Выбор m совершенно произволен и корректность алгоритма от него не зависит, но на эффективность влияет. Самый оптимальный вариант – средний элемент, т. к. на каждом шаге исключается половина массива. Задача исключить из дальнейшего поиска, каким бы ни был результат сравнения, как можно большее число элементов, поэтому оптимальным является выбор среднего элемента. В результате максимальное число сравнений имеет порядок log N. Т.о. приведенный алгоритм существенно эффективнее линейного, т.к. там ожидаемое число сравнений равно N/2.

Быстрый алгоритм построен на инварианте

(для любого K: 0<=k< α: ak<x)& (для любого K: r<=k<n : ak =>x)

Поиск продолжается пока обе секции не накроят массив целиком.

L:=0; R:=N-1; found:=false;

While L<=R and not found do Begin M:=(L+R) div 2 If a[m]=x then found=true else if a[m]<x then L:=m+1 Else R:=m-1; end. Условие окончания L=>R

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]