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

3.4. Длинная арифметика.

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

Пример 3.4.1.

Программа нахождения суммы двух

чисел.

X, Y – слагаемые

Z – сумма

P – перенос (флаг)

I, S – вспомогательные переменные

Пример функции реализующей сложение двух длинных чисел:

Turbo Pascal:

function LongSumm(X, Y: String): String;

var

P: Byte;

Z: String;

I: Integer;

S: Integer;

begin

while Length(X) < Length(Y) do

X := '0' + X;

while Length(Y) < Length(X) do

Y := '0' + Y;

Z := '';

P := 0;

for I := Length(X) downto 1 do

begin

S := Ord(X[I]) + Ord(Y[I]) - 96 + P;

if S < 10 then

begin

Z := Chr(S + 48) + Z;

P := 0;

end

else

begin

Z := Chr(S mod 10 + 48) + Z;

P := 1;

end;

end;

if P = 1 then

Z := '1' + Z;

LongSumm := Z;

end;

QBasic:

FUNCTION LongSumm$ (X AS STRING, Y AS STRING)

WHILE LEN(X$) < LEN(Y$)

X$ = "0" + X$

WEND

WHILE LEN(Y$) < LEN(X$)

Y$ = "0" + Y$

WEND

Z$ = ""

P = 0

FOR I = LEN(X$) TO 1 STEP -1

S = ASC(MID$(X$, I, 1)) + ASC(MID$(Y$, I, 1)) - 96 + P

IF S < 10 THEN

Z$ = CHR$(S + 48) + Z$

P = 0

ELSE

Z$ = CHR$(S MOD 10 + 48) + Z$

P = 1

END IF

NEXT I

IF P = 1 THEN

Z$ = "1" + Z$

END IF

LongSumm = Z$

END FUNCTION

Пример 3.4.2.

Программа нахождения разности двух чисел.

X, Y – уменьшаемое и вычитаемое

Z – разность

P – перенос

I, R – вспомогательные переменные

Программа на Turbo Pascal:

var

X, Y: String;

Z: String;

P: Byte;

I, R: Integer;

begin

ReadLn(X);

ReadLn(Y);

if (((Length(X) > Length(Y)) or ((Length(X) = Length(Y))))

and (X > Y)) then

begin

while Length(X) > Length(Y) do

Y := '0' + Y;

Z := '';

P := 0;

for I := Length(X) downto 1 do

begin

R := Ord(X[I]) - Ord(Y[I]) - P;

if R < 0 then

begin

Z := Chr(R + 58) + Z;

P := 1;

end

else

begin

Z := Chr(R + 48) + Z;

P := 0;

end;

end;

while (Z[1] = '0') do

Delete(Z, 1, 1);

WriteLn(Z);

end

else

WriteLn('Разность не найдена');

ReadLn;

end.

4. Рекурсия.

4.1. Понятие рекурсии.

Рекурсия – это способ определения процесса/объекта «в терминах самого себя», в терминах некоторого более простого случая этого же процесса/объекта. Рекурсивные определения используются во многих областях науки, особенно в математике. В математике рекурсией называется способ описания функций или процессов через самих себя. Примером рекурсивно описываемой функции является факториальная функция:

0! = 1;

для всех n > 0 n!= n*(n – 1)!,

которая для всех n > 0 определяется реккурентным соотношением через значение факториала от (n – 1); в свою очередь, (n - 1)! определяется через (n - 2)! и т. д. до сведения к значению 0!, которое определено явно и равно единице. Любое рекурсивное описание должно содержать явное определение функции для некоторых начальных значений аргументов, к которому сводится процесс вычисления значения функции в общем случае. Число промежуточных вычислений этой же функции в процессе вычисления ее значения для заданных аргументов – это глубина рекурсии. Для факториальной функции глубина рекурсии при любом значении аргумента очевидна (3! – глубина составляет 3 уровня). Однако обычно глубина рекурсии не является столь очевидной даже при простейших описаниях.

Рекурсивные определения часто используются и в информатике. В языках программирования рекурсия используется как способ описания подпрограмм (прежде всего функций), содержащих прямо или косвенно обращение к себе самой. Для исполнения таких подпрограмм требуется особая организация вычислительного процесса, так как при рекурсивных вычислениях необходимо сохранение информации об иерархии связей и локальных переменных всех рекурсивных вызовов, чтобы по окончании цепочки рекурсивных вызовов можно было восстановить каждое предшествующее прерванное состояние подпрограммы. Почти все системы рекурсивного программирования основываются на идее стека. Стеком является структура памяти магазинного типа LIFO (Last In First Out) – «последним пришел – первым ушел».

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

В общем случае для правильной организации рекурсивных алгоритмов необходимо выполнение двух условий:

  • должно быть найдено представление общей задачи в терминах «более простой» задачи того же класса, которое определит последовательность рекурсивных вызовов – база рекурсии;

  • рекурсивные вычисления не должны создавать бесконечную цепочку вызовов; для этого, во-первых, алгоритм должен включать хотя бы одно предписание, в котором при определенных условиях вычисление производится непосредственно, без рекурсивного вызова (терминальную ситуацию), а во-вторых, рекурсивные построения в конце концов должны сводиться к этим простым случаям.

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

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