Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Основы программирования. Борисенко

.pdf
Скачиваний:
1531
Добавлен:
09.04.2015
Размер:
9.31 Mб
Скачать

Арифметический

цикл

 

41

|

 

 

 

 

 

убыванию степеней

 

| надо: вычислить значение многочлена в точке t

начало

алгоритма

 

 

|

вещ p; цел

i ;

 

многочлена

|

p

:= 0.0;

// Инициализация значения

|

i

:= 0;

 

 

 

 

| цикл пока i <= n

// Вычисление нового значения по

|

| p

:= p * t + a [ i ] ;

|

|

 

 

// старому значению и добавленному

коэффициенту

|

| i

:= i + 1;

 

 

|

конец

цикла

 

 

|

ответ

:= p;

 

 

конец

алгоритма

 

 

А р и ф м е т и ч е с к ий цикл

 

 

 

В рассмотренных выше программах в цикле перебираются эле­

менты

массива

с индексом

i , где i пробегает значения от 0 до n — 1

(в последней

программе — от 0 до n, поскольку

многочлен n - й сте­

пени

имеет

n + 1 коэффициент). Д л я удобства

записи таких цик¬

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

переменная может

использоваться.

 

 

цикл для i от a до b

 

 

 

| . . .

 

 

 

 

 

 

| тело цикла

 

 

 

 

 

| . . .

 

 

 

 

 

 

конец цикла

 

 

 

 

 

 

Здесь переменная

цикла

i

последовательно

принимает значения от

a до b с шагом 1,

где a

и

b — некоторые

целочисленные

выраже­

ния. Таким образом, всего

тело

цикла выполняется b — a + 1 раз.

Если b меньше, чем a, то цикл

не выполняется ни разу.

Возможна

также конструкция арифметического цикла с шагом s, отличным от единицы:

42

 

 

 

1.5.1. Вычисление функций на последовательностях

 

цикл

для i от a до

b шаг s

 

 

 

| . . .

 

 

 

 

|

тело цикла

 

 

 

 

| . . .

 

 

 

 

конец

цикла

 

 

 

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

принимает значения a, a + s, a +

2s,

. . .

до

тех пор, пока

ее значение содержится в отрезке

[a,b].

Д л я

каждого значения переменной

цикла выполняется тело

цикла.

Шаг может быть и отрицательным, в этом случае b должно быть не больше, чем a, иначе цикл не выполняется ни разу.

В принципе, без конструкции арифметического цикла можно обойтись, поскольку ее можно смоделировать с помощью цикла "по­ ка". А именно, конструкция

цикл для i от a до b

| . . .

цикла

|

тело

| . . .

 

конец цикла

эквивалентна

конструкции

i

:= a

 

цикл пока i <= b

| . . .

цикла

|

тело

| . . .

 

| i := i + 1

конец цикла

Однако, традиционно арифметический цикл включается в большин¬

ство

языков высокого уровня.

С использованием арифметического

цикла схема Горнера переписывается следующим образом:

вещ

алгоритм

схема

Горнера(вх: цел n, вещ a[n+1], вещ t)

|

дано: n

--

степень

многочлена

|

 

a[n+1] -- массив коэффициентов многочлена по

|

надо: вычислить

убыванию

степеней

|

значение

многочлена в точке t

Индуктивные функции

на последовательностях

43

начало

алгоритма

 

 

|

вещ

p;

цел i ;

// Инициализация значения

многочлена

|

p := 0.0;

|

цикл для i от 0 до n

 

|

| p

:=

p * t +

a [ i ] ; // Вычисление нового значения

|

|

 

цикла

// при добавлении

коэффициента

|

конец

 

 

|

ответ

:= p;

 

 

конец

алгоритма

 

 

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

вещ алгоритм

схема Горнера2(вх: цел n, вещ b[n+1], вещ t)

|

дано: n

 

 

степень

многочлена

|

 

 

b[n+1]

-- массив

коэффициентов многочлена по

|

 

 

 

 

 

возрастанию степеней

|

надо: вычислить значение многочлена в точке t

начало

алгоритма

 

 

|

вещ

p;

цел

i ;

// Инициализация значения многочлена

|

p :=

0.0;

i

от

|

цикл

для

n до 0 шаг -1

|

| p

:=

p

* t

+ b [ i ] ;

//

Вычисление нового значения

|

|

 

цикла

 

// при добавлении коэффициента

|

конец

 

 

 

|

ответ

:=

p

 

 

 

 

конец алгоритма

 

 

 

И н д у к т и в н ые

ф у н к ц и и

на

последовательностях

ииндуктивные расширения

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

44

1.5.1. Вычисление функций на последовательностях

функции и

добавленный элемент. Обозначим через S n последова¬

тельность

 

 

S n = { Й О , a i , . . . , a n - i }

длины n. С помощью знака & обозначим операцию приписывания нового элемента справа к последовательности (ее называют т а к ж е конкатенацией):

Sn+i = S n & a n = {ЙО, a i , . . . , Й П - 1 , ЙП}.

Пусть / (S ) — некоторая функция на множестве последовательно­ стей, например, сумма элементов последовательности. Ф у н к ц и я на¬ зывается индуктивной, если при добавлении нового элемента к по¬ следовательности новое значение функции можно вычислить, зная только старое значение функции и добавленный элемент. На мате¬ матическом языке функция

/ : W - Y,

где W — множество всех последовательностей, составленных из эле­ ментов некоторого множества X , индуктивна, если существует функ­ ция G от двух аргументов

 

G : Y х X

Y

 

 

такая, что для любой последовательности

S из W и любого

элемента

a из X

значение функции / на последовательности

S, к

которой

добавлен

элемент a, вычисляется с помощью функции

G:

 

/(S & a) = G ( / ( S ) , a ) .

Фу н к ц и я G по паре (y,a), где y — старое значение функции / на последовательности S и a — элемент, добавленный к последователь¬ ности, вычисляет новое значение y, равное значению функции / на новой последовательности.

Впримере с суммой элементов последовательности функция G равна сумме элементов y и a:

G ( y , a ) = y + a.

Индуктивные функции на последовательностях

45

В примере с максимальным элементом последовательности

функция

G равна максимуму:

 

G ( y, a) = max(y, a).

 

В примере со схемой Горнера вычисления значения многочлена в точке t, где коэффициенты многочлена заданы в последовательности по убыванию степеней, функция G равна

G(y, a) = yt + a.

Во всех трех случаях рассматриваемая функция на последовательно¬ сти индуктивна.

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

алгоритм

значение индуктивной функции(

)

вх: последовательность S

дано: последовательность S

|

| надо: вычислить функцию y = f(S)

начало

алгоритма

| y :=

значение функции f на пустой последовательности;

|

встать в начало последовательности S;

| цикл пока в последовательности S есть

|

|

 

непрочитанные элементы

|

| прочесть очередной элемент

|

|

:=

последовательности S в (вых^);

|

| y

G(y, x);

|

конец

цикла

|

ответ

:= y;

конец алгоритма

Таким образом, для каждой конкретной индуктивной функции надо лишь правильно задать ее значение на пустой последовательности (инициализация) и определить, как новое значение функции вычис¬ ляется через старое при добавлении к последовательности очеред¬ ного элемента, т.е. задать функцию G ( y , x ) . Схема вычисления для всех индуктивных функций одна и та же .

46

1.5.1. Вычисление функций на последовательностях

Однако, не все функции на последовательностях являются ин­ дуктивными. Рассмотрим следующий пример. Пусть коэффициенты многочлена заданы в последовательности по убыванию степеней. На­ до вычислить значение производной многочлена в точке x = 2. Обо¬ значим через

S = {ЙО, a i , . . . , a „ |

последовательность коэффициентов многочлена

p(x) = a 0 x n + a 1 x n — 1 + . . . + an

и через / ( S ) значение производной многочлена p'(x) в точке x = 2:

/ ( S ) = Р'(2).

Покажем, что функция / не индуктивна. Достаточно указать две

последовательности

S 1 и S 2 , такие, что значения функции /

на них

совпадают, но при добавлении к последовательностям

S 1 и S 2

одного

и того ж е элемента

a новые значения функции у ж е не

равны:

 

/ ( S i ) = / (S2),

/ ( S i & a) = /(S2 & a).

Возьмем последовательности

 

51

=

{1},

 

52 =

{1, —4,1}.

Им соответствуют многочлены

 

 

P i (x)

=

1,

 

p 2

(x)

=

x 2

— 4x + 1.

Производные многочленов

равны

 

 

Pi(x)

=

0,

 

p2(x) =

2x — 4.

Значения обеих производных в точке x = 2 равны нулю, т.е.

/ ( S i ) = pi(2)

=

0,

/ ( S 2 ) = p2(2)

=

2 • 2 — 4 = 0.

Индуктивные функции на последовательностях

47

Припишем теперь к обеим последовательностям элемент a = 1:

S i

& 1

=

{1,1},

 

 

 

& 1

=

{1, —4,1,1}.

Новым последовательностям соответствуют

многочлены

qi

(x)

=

x + 1,

 

 

q2

(x)

=

x 3

— 4 x 2 + x +

1.

Их производные равны

 

 

 

 

 

 

qi (x)

=

1,

 

 

q2 (x)

=

3 x 2

— 8x + 1.

Значения производных в точке x =

2 равны

соответственно

/ ( S i & 1 )

=

qi (2)

=

1,

 

/ ( S 2 & 1) =

q2 (2) =

12 — 16 +

1 = —3.

М ы

видим,

что

значения / ( S i )

и

/ ( S 2 )

совпадают, но значения

/ ( S i

& 1 ) и

/ ( S 2

& 1 ) не совпадают.

Следовательно, функция /

не

индуктивна.

 

 

 

 

 

Как поступать в случае, когда функция

/ не индуктивна? Общий

рецепт следующий: надо придумать индуктивную функцию F , такую,

что, зная значение F , легко можно вычислить исходную функцию

/ .

Ф у н к ц и я F называется индуктивным

расширением функции / .

 

Приведем формальные определения. Пусть исходная функция на

множестве

W всех последовательностей

 

 

 

 

 

/ : W

Y

 

 

не индуктивна. Индуктивная функция

F : W — Z

называется индуктивным расширением функции / , если существует отображение

P : Z — Y

такое, что для всякой последовательности S, принадлежащей W , вы¬ полняется равенство

/ ( S ) = P ( F ( S ) )

48

 

1.5.1. Вычисление функций на последовательностях

(т.е. функция

/

равна композиции отображений F и P ,

/

= P о

F . )

Отображение

P

обычно называют проекцией множества

Z

на Y .

 

Как построить индуктивное расширение функции / ? Это творче¬ ский момент, готового рецепта на все случаи не существует. Нефор¬ мальный рецепт следующий: надо понять, какой информации не хва¬ тает для того, чтобы уметь вычислять новое значение последова¬ тельности при добавлении к ней нового элемента. Эту информацию надо хранить дополнительно к значению последовательности. Отсю¬ да и появился термин «расширение»: вычисляется более сложная, расширенная, функция, чтобы по ней затем восстановить исходную. Как правило, значением индуктивного расширения F является пара (y, h), где y — значение исходной функции / , а h — некоторая допол­ нительная информация, позволяющая перевычислять значение y при добавлении нового элемента к последовательности. Таким образом,

множество Z значений индуктивного

расширения

F : W -

Z

чаще всего является множеством пар (y,h), т.е. декартовым произ¬ ведением:

Z = Y х Я .

Отображение P на практике должно легко вычисляться. Так оно и есть в случае декартого произведения — это просто проекция на первый аргумент.

P ( У , h) = y.

Рассмотрим пример с вычислением производной многочлена в точке; коэффициенты многочлена заданы в последовательности по убыванию степеней. При добавлении к последовательности

 

Sk =

Й Ъ .

. . , a k }

нового

коэффициента ak+i получаем

последовательность

 

S k + i = S k & a k + i = { a 0 , a i, . . . , a k , a k + i } .

Пусть

этим двум последовательностям

соответствуют многочлены

Pk (x) и pk+i(x). Тогда

 

 

 

 

Pk+i (x) =

Pk (x)

• x +

ak+i.

Индуктивные функции на последовательностях

49

Дифференцируя это равенство, получим:

Pk+i(x) = Pk (x) • x + pk.

М ы видим, что для вычисления нового значения производной нужно знать старое значение производной, а также старое значение много¬ члена. Следовательно, дополнительно к значению производной мно¬ гочлена надо хранить еще значение самого многочлена. Таким обра¬ зом, индуктивным расширением функции, равной производной мно¬ гочлена в точке t, является пара (значение производной, значение многочлена):

F : S — (P(t),P(t)).

Новое значение производной вычисляется по приведенной выше фор¬ муле через старое значение производной и старое значение много¬ члена. После этого вычисляется новое значение многочлена по схеме Горнера.

Выпишем алгоритм вычисления производной многочлена.

вещ алг. значение производной(вх: цел n, вещ a[n+1], вещ t)

| дано:

n

степень

многочлена

|

a[n+1]

массив

коэффициентов многочлена по

|

 

возрастанию степеней

| надо: найти значение производной многочлена в точке t

начало алгоритма

 

 

 

 

|

вещ p, dp; цел i ;

 

 

 

|

p

:= 0.0;

// Инициализация

значения

многочлена

|

dp

:= 0.0;

// Инициализация

значения

производной

| цикл для i от 0 до n

// Новое

значение

производной

|

| d p : = d p * x + p ;

|

| p := p * t + a [ i ] ;

// Новое

значение

многочлена

|

конец

цикла

 

 

 

 

|

ответ

:= dp;

 

 

 

 

конец алгоритма

Другой пример неиндуктивной функции — это среднее арифме¬ тическое значение элементов последовательности. Индуктивным рас¬ ширением является пара (сумма элементов последовательности, дли¬ на последовательности):

F (S) = ( с у м м а ^ ) , д л и н а ^ ) ) .

50

1.5.1. Вычисление функций на последовательностях

Легко видеть, что функция F индуктивна. При известном значении функции F не составляет труда вычислить исходную функцию:

среднее а р и ф м е т и ч е с к о е ^ ) = с у м м а ( S ) / д л и н а ( 5 ) .

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

Итак, в каждом конкретном случае при вычислении неиндуктив¬

ной функции

/

надо придумать ее индуктивное расширение

F

и в

программе вычислять сначала индуктивное расширение

F , а

затем

по значению

F

вычислять требуемое значение исходной

функции

/ .

За д а чи по теме «Индуктивные ф у н к ц и и »

1.Указать, какие из нижеперечисленных функций на последо¬ вательностях являются индуктивными. В каждом случае надо привести доказательство индуктивности или неиндуктивности функции. Д л я неиндуктивных функций построить их индук¬ тивные расширения:

произведение элементов последовательности;

число максимальных элементов последовательности;

число локальных максимумов последовательности (эле¬ мент является локальным максимумом, если он не меньше своих соседей);

сумма первого и последнего элементов последовательно¬ сти;

число перемен знака в последовательности;

значение многочлена, коэффициенты которого заданы по возрастанию степеней, в точке x = 1;

— та ж е задача при x = —1;

вторая производная многочлена, коэффициенты которого заданы по убыванию степеней, в точке x = 2.