Основы программирования — Осенний семестр; Михалкович С.С.; 2008; I — различия между версиями
Admin (обсуждение | вклад) (→Вложенные циклы) |
Admin (обсуждение | вклад) (→Ссылки) |
||
Строка 967: | Строка 967: | ||
==Ссылки== | ==Ссылки== | ||
− | *[ | + | *[%D0%9E%D1%81%D0%B5%D0%BD%D0%BD%D0%B8%D0%B9_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80%3B_%D0%9C%D0%B8%D1%85%D0%B0%D0%BB%D0%BA%D0%BE%D0%B2%D0%B8%D1%87_%D0%A1.%D0%A1.%3B_2008%3B_II Вторая часть конспекта] |
*[[Конспекты|Другие конспекты]] | *[[Конспекты|Другие конспекты]] |
Версия 00:28, 12 февраля 2009
Содержание
- 1 Алгоритм
- 2 Правила записи программ на Object Pascal
- 3 Синтаксис и семантика ЯП
- 4 Переменные и их описание
- 5 Типы
- 6 Оператор присваивания :=
- 7 Оператор ввода
- 8 Оператор try/except и обработка ошибок ввода
- 9 Оператор вывода
- 10 Условный оператор
- 11 Арифметические выражения
- 12 Логические выражения
- 13 Побитовые операции
- 14 Таблица приоритетов операций языка Object Pascal
- 15 Оператор case выбора варианта
- 16 Циклы с предусловием (while) и постусловием (repeat)
- 17 Оператор цикла с параметром (for)
- 18 Примеры использования циклов
- 18.1 Пример 1. Табулирование функции
- 18.2 Рекуррентные соотношения
- 18.3 Пример 2. Вывод степеней двойки
- 18.4 Пример 3. Последовательность Фибоначчи
- 18.5 Пример 4. Вычисление НОД (алгоритм Евклида)
- 18.6 Пример 5. Суммирование рядов (конечных и бесконечных)
- 18.7 Пример 6. Нахождение max в последовательности чисел
- 18.8 Пример 7. Разложение целого числа на простые множители
- 18.9 Операторы break и continue
- 18.10 Пример 8. Поиск заданного значения среди введенных
- 18.11 Пример 9. Обработка последовательности, завершающейся нулем
- 18.12 Пример 10. Вычисление значения многочлена. Схема Горнера
- 18.13 Пример 11. Поиск нуля функции на отрезке
- 19 Вложенные циклы
- 20 Ссылки
Алгоритм
Лекция 1
Свойства алгоритма
- дискретность
- элементарность команд
- определенность команд
- каждая команда имеет четкое однозначное значение
- конечность
- каждый А. должен когда-то завершаться при любом наборе исходных данных
- результативность
- после выполнения А. известно, что считать результатом
- массовость
- применимость ко множеству исходных данных
Связанные понятия
Спецификация задачи — точное, однозначное описание задачи. Включает формулировку входных и выходных данных.
Исполнитель алгоритма — устройство, имеющее некоторую систему команд, и способное их исполнять.
- Процессор — исполнитель машинных кодов.
Пример
- Дано: x,y,z.
- Найти max
А.1. (словесное описание).
Если x>y и x>z, то максимум - это x Если y>x и y>z, то максимум - это y Если z>x и z>y, то максимум - это z
А.2. (псевдокод).
max := x Если y<max то max := y Если z<max то max := z
Эквивалентными называются алгоритмы, имеющие одинаковые наборы исходных данных и выдающие одинаковый результат при одинаковых исходных данных.
Способы описания алгоритмов
- словесный
- псевдокод
- блок-схемы
Пример. А.2., представленный блоксхемой.
- диаграммы деятельности (activity diagram) UML
Пример. А.2., представленный диаграммой деятельности
- язык программирования (ЯП)
Команды алгоритма также называются:
- операторы Я.
- инструкции Я.
Правила записи программ на Object Pascal
По Шпаргалке
- Пример программы, вычисляющей длину и площадь круга.
- Общие правила записи программ на Паскале. Оформление, комментарии
PascalABC.NET. Как скачать, инсталлировать. (сайт системы программирования PascalABC.NET)
Лекция 2
Синтаксис и семантика ЯП
Определения
Синтаксис — формальные правила описания конструкций ЯП.
Семантика — описывает смысл конструкций ЯП, а также задает ряд ограничений.
Способы описания синтаксиса
- БНФ (Бэкуса-Наура формы, 1960, Алгол-60).
Пример.
<цифра> ::= 0|1|2|3|4|5|6|7|8|9 <идентификатор> ::= <буква> | <идентификатор><буква> | <идентификатор><цифра>
0, 1, ... 9
- называют терминалами (лексемами) — это "конечные символы", т.е. по умолчанию известные в ЯП.
<цифра>
- так называемый нетерминал (нетерминальный символ).
- Он определяется через терминалы, другие нетерминалы и самого себя. Причем в последнем случае правило задания нетерминала называется рекурсивным (как определение нетерминала <идентификатор>)
- РБНФ (Расширенные БНФ)
- [] — 0 или 1 повторение.
- {} — 0 и более повторений
Пример.
<идентификатор> ::= <буква> {<буква> | <цифра>}
- Синтаксические диаграммы (Вирт, Паскаль)
Грамматика языка — совокупность всех синтаксических правил данного ЯП, обычно заданных в форме БНФ.
- Грамматика не учитывает все виды ошибок, в ЯП формулируются дополнительные семантические правила.
Замечание 1. Способы 1-3 эквивалентны.
Замечание 2. Синтаксис определяет лексемы языка.
Лексемы Паскаля
- спецсимволы: := += *
- ключевые слова (begin, end, if, for)
- идентификаторы (a, b1)
- константы (2, 'ABC', #5)
- комментарии (3 вида)
- {...}
- (*...*)
- //...
Обзор современных ЯП
(самостоятельно на форуме)
Переменные и их описание
Основные сведения
Переменная — это ячейка памяти компьютера, имеющая имя и тип.
- Тип определяет размер переменной и множество принимаемых ею значений.
В языке Pascal любая переменная перед использованием должна быть описана.
Обычно переменные описываются в разделе описаний.
Синтаксис в виде РБНФ
<программа> ::= [program <имя>;] <раздел описаний> begin <операторы> end. <операторы> ::= <оператор>{; <оператор>} <раздел описаний> ::= {<секция раздела описаний>} <секция раздела описаний> ::= <секция описания переменных> | <с.о. констант> | <с.о. типов> | <с.о. подпрограмм>...
Пример секции описания переменных
var
a,b: real;
i: integer;
<секция описания переменных> ::= var<подсекция>{< подсекция>} <подсекция> ::= <список имен>: <тип>; <список имен> ::= <имя>{,<имя>} <тип> ::= <имя>
Внутриблочные переменные
В PascalABC.NET возможно внутриблочное описание переменных:
begin
var i,j: integer;
var r: real := 5.2;
var Pi := 3.14;
В последнем случае происходит автоопределение типов.
Типы
- Целые
- integer (4 байта)
- shortint (1)
- smallint (2)
- int64 (8)
- Вещественные
- real (8)
- single (4)
- Символьные
- char (2 — Unicode)
- Строковые
- string
- string[200]
- shortstring = string[255]
- Логический
- boolean (1) | [True False]
Оператор присваивания :=
Синтаксис
<переменная> := <выражение>
Пример использования оператора присваивания
a := (3 + 5) * 8; b := a + 2;
Семанитика
Вычисляется выражение в правой части, при этом вместо имен переменных подставляются их значения. Затем результат вычисления записывается в переменную в левой части.
Ограничение. Тип выражения должен быть совместим по присваиванию с переменной. Например:
- одинаковые типы совместимы.
- выражение типа integer можно присвоить переменной типа real, обратное неверно.
Операторы присваивания += и *=
Пример.
d += 1; //прибавить 1 к d d *= 2; //умножить d на 2
Лекция 3
Примеры использования :=
Пример 1. Перемена местами двух значений.
- Дано: x,y;
var x,y: integer;
begin
read(x,y);
var v := x;
x := y;
y := v;
writeln(x,' ',y);
end.
Это стандартное решение. В PascalABC.NET на основе этого алгоритма определена стандартная процедура Swap(x, y).
Однако, существуют и другие решения. Например:
var x,y: integer;
begin
read(x,y);
x := x + y;
y := x - y;
x := x - y;
writeln (x, ' ', y);
end.
Пример 2. Использование промежуточных переменных в вычислениях
- Дано: x: real;
- Найти: x15;
Решение 1.
y := x * x;
z := y * y;
t := z * z;
p := t * z;
q := p * x * y;
Решение 2.
y := x * x;
z := y * x;
t := z * y;
p := t * t * t;
Решение 3.
y := x * x;
x := x * y * y;
t := x * x * x;
Заметим, что в первом решении используется 6 операций умножения, в во 2м и 3м — 5. Возникает задача:
- найти xn за минимальное число умножений.
- Об этом читай тему.
Оператор ввода
Синтаксис
read (<список переменных>) | readln (<список переменных>)
Семантика
Происходит считывание данных с клавиатуры и запись их в переменные из <списка переменных>. Вводить данные нужно либо через пробел, либо по нажатию <Enter>, при этом программа не перейдет к выполнению следующего оператора, пока не будут считаны все данные.
С процедурой ввода связан ряд ошибок (например, если переменная используется в качестве делителя и вводится 0, или если должно быть получено целое число, а вводится 'ABC'). Эти ошибки нужно уметь обрабатывать.
Оператор try/except и обработка ошибок ввода
Операторы, которые могут получать ошибку, заключаются специальный охранный блок - оператор try.
Синтаксис
try
...
readln(a);
...
except
<обработка ошибки>
end;
<продолжение работы>
Семантика
Если внутри блока try происходит ошибка выполнения, то все последующие операторы в блоке игнорируются и выполнение программы переходит к блоку except. По выходе из except программа продолжает работу.
Если ошибки не происходит, то выполняются все операторы в блоке try, блок except не выполняется и программа продолжает работу.
Оператор вывода
Синтаксис
write( <список выражений> ) | writeln( <список выражений> )
Семантика
Выражения в списке вычисляются и тих значения выводятся на экран. В случае writeln после выводао существляется переход на новую строку.
Форматы вывода
После каждого выражения в списке вывода можно использовать формат вывода в виде :a, где a — выражение целого типа. После вещественного типа — :a:b
a задает ширину поля вывода ( выравнивание по правому краю ).
b — количество знаков в дробной части.
Вывод с помощью write[ln]Format
writelnFormat( '<форматная строка>', <список выражений> )
Пример вывода с использованием форматной строки
writelnFormat('{0} * {1} = {2}', a, b, a * b);
Будет выведено:
a * b = a * b
В форматной строке тоже можно использовать формат вывода.
{0, 10} — 10 это ширина поля вывода
{0, 10:f3} — 3 это количество знаков в дробной части для вещественного числа (показывает это спецификатор f).
Условный оператор
Синтаксис
if <условие> then <оператор1> else <оператор2>
Семантика
Примеры использования для решения задач
Пример 1. Нахождение минимума
Дано: x,y;
Найти: min;
if x > y then
min := y
else
min := x;
Пример 2. Упорядочение a, b по возрастанию
Ясно, что если a>b, — нужно поменять их местами.
Но тут одним оператором не обойтись.
Для этого можно использовать составной оператор — один или больше операторов, заключенных в операторные скобки begin - end;:
if a > b then
begin
var v := b;
b := a;
a := v;
end;
Пример 3. Вычисление функции по взаимоисключающим веткам
<math> y = \begin{cases} x, & x < 2 \\ x^2, & 2 < x < 3 \\ 1-x, & x \ge\; 3 \end{cases}</math>
if x < 2 then
y := x
else
if x < 3 then
y := x * x
else
y := 1 - x;
Замечание. Если по ветви else располагается другой оператор if, то говорят, что возникает цепочка вложенных операторов if.
Пример 4. Найти среднее среди a,b,c (a,b,c попарно не равны) Эта задача имеет несколько вариантов решения.
if a < b then
if a < c then
if b < c then
sr := b
else
sr := c
else
sr := a
else
if a > c then
if b > c then
sr := b
else
sr := c
else sr := a;
Очевидно, это не самое лучшее решение.
Можно воспользоваться стандартными функциями сравнения.
sr := min(a,b);
if sr < c then
sr := min(max(a,b), c);
Самостоятельно.
- Даны координаты вершин треугольника и точка M. Принадлежит ли M треугольнику.
- Является ли 4-угольник ABCD корректно заданным.
Лекция 4
Арифметические выражения
Основные сведения
Каждое выражение имеет тип. Выражение называется арифметическим, если его тип — числовой. Выражение строится посредством операций( унарных или бинарных ) и операндов.
В арифметических выражениях если a и b — одного типа, то и a op b принадлежит к тому же типу. Исключением является операция "/":
- a / b — вещественное.
Если a и b принадлежат к различным тиапм, то выражение принадлежит к "старшему" типу.
Например:
byte < integer < int64 integer < real
В арифметические выражения могут входить стандартные функции:
- exp(x)
- ln(x)
- abs(x) // модуль x
- sin(x)
- cos(x)
- sqr(x) // квадрат x
- sqrt(x) // корень из x
- min(x,y)
- max(x,y)
- pow(x,y) // x в степени y
Порядок выполнения операций в арифметических выражениях
- Операции с большим приоритетом выполняются первыми
- Функции вычисляются до операций
- Выражение в скобках вычисляется раньше
- Операции с одинаковым приоритетом выполняются слева направо, если идут подряд.
Операции div и mod для целых
x div y = x / y, округленное до ближайшего целого по направлению к нулю. Это результат от целочисленного деления.
x mod y = x - (x div y) * y. Это остаток от целочисленного деления.
Пример использования
Целочисленные операции часто применяются для определения четности числа:
x mod 2 = 0 <-> x — четное x mod 2 <> 0 <-> x — нечетное
Логические выражения
Основные сведения
Выражение назывется логическим, если оно имеет тип boolean.
Пример.
x < 0 a >= b a <> 3
Это простые логические выражения. Однако, с помщью логических операций можно составлять сложные.
( бинарные ) ( унарные ) a and b not a a or b a xor b
Таблицы истинности логических операций
a | b | a and b | a or b | a xor b T | T | T | T | F T | F | F | T | T F | T | F | T | F F | F | F | F | T
Сокращение вычислений логических выражений
Большинство современных компиляторов, в т.ч. PascalABC.NET производит сокращенное вычисление логических выражений.
Это означает, что в выражении
a and b
если a — ложно, то b не вычисляется, а в
a or b
если a — истинно, b не вычисляется.
Это очень полезно при вычислении таких выражений, как, например,
( y <> 0 ) and (x / y > 0 )
Логически здесь все верно, однако, если бы не использовалось сокращенное вычисление, в случае равенства нулю y возникала бы ошибка деления на ноль.
Логические переменные
Можно описывать логические переменные ( тип boolean ). Им можно присваивать логические выражения.
Эти переменные принимают одно из двух возможных значений:
- true ( истина )
- false ( ложь )
Пример использования логических переменных
- Дано: прямоугольник со сторонами, параллельными осям координат, задан координатами абсцисс вертикальных сторон ( x1, x2 ) и ординатами горизонтальных ( y1, y2 ); точка M( x, y );
- Найти: находится точка внутри прямоугольника, снаружи, или лежит на границе;
var inside, outside, bound: boolean;
begin
inside := (x > x1) and (x < x2) and (y > y1) and (y < y2);
outside := (x < x1) or (x > x2) or (y < y1) or (y > y2);
bound := not inside and not outside;
end.
Побитовые операции
Побитовые операции and, or, xor
Замечание. Работают только с целыми.
Смысл такой — каждое целое переводится в двоичную систему счисления и производится побитовое применение этих операций.
Пример
5 and 10
510 = 1012
710 = 1112
101 ( and ) 111 ——— 1012 = 510
Операции shl и shr
Побитовый сдвиг влево и сдвиг вправо соответственно.
shl
x shl n = x * 2n
Сдвигает двоичное представление x на n позиций влево.
shr
x shr n = x div 2n
Сдвигает двоичное представление x на n позиций вправо.
Примеры
x = 510 = 1012 x shl 2 = <—(2)101 101002 = 2010 x shr 2 = 101—>(2) 0012 = 110
Таблица приоритетов операций языка Object Pascal
- унарные + - not
- имеющие смысл умножения * / div mod and shl shr
- имеющие смысл сложения + - or xor
- операции отношения <> <= >= < > in
Оператор case выбора варианта
Синтакстис
case <переключатель> of {<список выбора>: <оператор>;} [else <оператор>[;]] end
Семантика
Вначале вычисляется выражение-переключатель, после чего его значение ищется в одном из <списков выбора>.
Если значение попадает в какой-то <список выбора>, то выполняется соответствующий ему оператор, иначе, если есть ветвь else, то выполняется оператор по ветке else.
Ограничения
- выражение-переключатель должно иметь так называемый порядковый тип:
- целый
- символьный
- перечислимый
НО НЕ строковый или вещественный.
- значения в <списках выбора> не должны пересекаться.
Примеры использования оператора выбора
Пример 1. День недели
case DayOfWeek of
1..5: writeln('Будний');
6,7: writeln('Выходный');
else writeln('Ошибка');
end;
Пример 2. Цифра или буква
var c: char;
read(c);
case c of
'0'..'9': writeln('Цифра');
'A'..'Z', 'a'..'z', 'а'..'я', 'А'..'Я', 'ё', 'Ё': writeln('Буква');
end;
Лекция 5
Циклы с предусловием (while) и постусловием (repeat)
Синтаксис цикла while
while <условие> do <— заголовок цикла <оператор> <— тело цикла <условие>::= <логическое выражение>
Семантика цикла while
Синтаксис цикла repeat
repeat <операторы> until <условие>
Семантика цикла repeat
Зацикливание
Зацикливание происходит, если:
- условие цикла с предусловием всегда истинно
Пример
while true do
<оператор>
- условие цикла с постусловием всегда ложно
Пример
repeat
<операторы>
until false
Итерация — однократное повторение тела цикла
Отличия между циклами while и repeat
while
- тело может не выполниться ни разу
repeat
- тело выполнится хотя бы один раз
Примеры
Пример 1. Сумма нечетных двузначных чисел
С использованием while
s := 0; x := 11;
while x < 100 do
begin
s += x;
x += 2;
end;
С использованием repeat
s := 0; x := 11;
repeat
s += x;
x += 2;
until x = 99;
Пример 2. Факториал
С использованием repeat
var n: integer;
read(n);
var x := n;
var p :=1;
repeat
p *= x;
x -= 1;
until x = 1;
С использованием while
var n: integer;
read(n);
var x := n;
var p :=1;
while x > 1 do
begin
p *= x;
x -= 1;
end;
Моделирование repeat с помощью while
repeat Op Op ——> while not A do until A; begin Op end;
Моделирование while с помощью repeat
while A do if A then Op ——> repeat Op until not A
Оператор цикла с параметром (for)
Синтаксис
<заголовок цикла> <тело цикла>
<заголовок цикла> ::= for <переменная>:=<выражение1> <направление> <выражение2> do <тело цикла> ::= <оператор> <направление> ::= to | downto
Семантика
var b := <выражение1>;
var e := <выражение2>;
<переменная> := b;
while <переменная> <> e do
begin
<оператор>
<получить следующее значение переменной>
<переменная> += 1; | <переменная> -= 1;
end;
<получить следующее значение переменной> ::= <переменная> += 1; | <переменная> -= 1;
Ограничения:
- выражения 1 и 2 должны быть совместимы по присваиванию с переменной
- переменная должна иметь порядковый тип ( такой же, как и в case — целый, символьный или перечислимый )
- переменная цикла for не должна меняться внутри цикла for
- переменная цикла for должна быть описана в той же п/п, где используется цикл
Дополнительные возможности PascalABC.NET
Возможно описание переменной цикла в его заголовке:
for [var] i: integer := 1 to 5 do
<оператор>
Возможно автоопределение типа при описании:
for var i := 1 to 5 do
<оператор>
Переменная цикла, описанная в заголовке цикла, определена только внутри цикла. Замечание! Значение переменной цикла после завершения цикла не определено. Именно поэтому рекомендуется описывать переменную цикла в заголовке цикла.
Примеры использования циклов
Пример 1. Табулирование функции
- Дана f(x) на [a; b], разбитая на N частей.
- Выдать таблицу значений в точках разбиения.
Решение
var a, b: real;
var N: integer;
read(a, b, N);
assert(N <> 0);
assert(b > a);
var h := (b - a) / N;
Дальнейшее решение с помощью for:
for var i:=0 to N do
begin
writelnFormat('{0,6:f2} {1,9:f4}', x, f(x));
x += h;
end;
Дальнейшее решение с помощью while:
var eps := h / 2;
while x < (b + eps) do
begin
writelnFormat('{0,6:f2} {1,9:f4}', x, f(x));
x += h;
end;
Замечание. Вещественные числа в памяти компьютера представлены приближенно. Ошибка, которая возникает при представлении вещественного числа в памяти, называется ошибкой округления.
Ошибка, которая возникает в результате вычислений с вещественными числами называется вычислительной погрешностью.
- Вывод. Вещественные числа нельзя сравнивать на равенство, можно только на больше/меньше.
Лекция 6
Рекуррентные соотношения
Говорят, что последовательность данных
x1, x2, x3,..., xn
является рекуррентной, если
xk + 1 = f( xk ), k = 1, 2, 3...
Пример 2. Вывод степеней двойки
var x := 1;
for var i:=1 to 10 do
begin
writeln(x);
x *= 2;
end;
Пример 3. Последовательность Фибоначчи
<math>\begin{cases} x_1 = 1, x_2 = 1 \\ x_{k+1} = x_k + x_{k-1}\end{cases}</math>
var a := 1;
var b := 1;
write(a, ' ', b, ' ');
for var i := 3 to 20 do
begin
c := a + b;
write(c, ' ');
a := b;
b := c;
end;
Пример 4. Вычисление НОД (алгоритм Евклида)
<math>\begin{cases} x_1 = a \\ x_2 = b \\ x_{k+1} = x_{k-1} mod x_k\end{cases}</math>
Решение
var a, b: integer;
read(a, b);
assert((a > 0) and (b > 0));
repeat
c := a mod b;
a := b;
b := c;
until c = 0;
writeln(a);
Пример 5. Суммирование рядов (конечных и бесконечных)
- <math> \sum_{i=1}^n \frac{a^i}{i!}</math>
Найдем рекуррентную связь между ai:
x1 = a xi = xi-1 * a / i, i = 2, 3..
Решение
read(a, n);
x := a;
s := x;
for var i:=2 to n do
begin
x *= a / i;
s += x;
end;
- <math> \sum_{i=1}^\infty (-1)^i\frac{a^i}{i}</math>
Для вычисления суммы бесконечного ряда в простейшем случае используют следующий метод:
- задается некоторый малый eps и сумма <math>\sum_{i=1}^\infty x_i</math> вычисляется, пока <math>|x_i| <\ eps</math>
Решение
assert((a > 0) and (a < 1));
i := 1;
s := 0;
y := -a;
repeat
s += y / i;
i += 1;
y *= -a;
until abs(y / i) < eps;
Пример 6. Нахождение max в последовательности чисел
Решение
max := - real.MaxValue;
for var i:=1 to n do
begin
read(x);
if x > max then
max := x;
end;
Пример 7. Разложение целого числа на простые множители
Будем делить x на p, начиная с p = 2. Если делится нацело, то p — множитель, если не делится, то увеличиваем p на 1, пока x <> 1.
Решение
read(x);
p := 2;
repeat
if x mod p = 0 then
begin
write(p, ' ');
x := x div p;
end
else
p += 1;
until x = 1;
Лекция 7
Операторы break и continue
break — оператор досрочного завершения цикла.
continue — оператор досрочного завершения текущей итерации цикла.
Пример 8. Поиск заданного значения среди введенных
Решение 1. С использованием оператора break
var exists: boolean := false;
for var i:=1 to n do
begin
read(x);
if x = k then
begin
exists := true;
break;
end;
end;
Решение 2
var i := 1;
var exists: boolean:= false;
repeat
read(x);
if x = k then
exists := true;
i += 1;
until (i > n) or exists;
Пример 9. Обработка последовательности, завершающейся нулем
- Вводятся числа. Конец ввода — ноль.
- Найти сумму и произвведение положительных чисел.
Решение
s := 0;
p := 1;
while True do
begin
read(x);
if x = 0 then
break;
if x < 0 then
continue; //фильтр
s += x;
p *= x;
end;
Пример 10. Вычисление значения многочлена. Схема Горнера
Необходимо вычислить <math>\ a_0x^n + a_1x^{n-1} + ... + a_{n-1}x + a_n</math> если
- a0...an известны
- x дано
Решение1
var p := 1.0;
var s := 0.0;
for var i:=0 to n do
begin
read(a);
s += p * a;
p *= x;
end;
Это решение использует 2(n + 1) умножений.
Однако есть и другое решение — схема Горнера.
Оно основана на том, что
<math>\ a_0x^2 + a_1x + a_2 = ((a_0)x + a_1)x + a_2</math>
Решение2
read(a);
var res: real := a;
for var i:=1 to n do
begin
read(a);
res *= x;
res += a;
end;
Итого — всего n умножений.
Пример 11. Поиск нуля функции на отрезке
Требуется найти корень уравнения f( x ) = 0
- на отрезке [a; b]
- с заданной точностью eps
- f(x) непрерывна на этом отрезке
- имеет на нем ровно 1 корень, т.е. f(a ) * f( b ) < 0
Эта задача решается методом половинного деления.
assert(b > a);
var fa := f(a);
var fb := f(b);
assert(fa * fb < 0);
while b - a > eps do
begib
var x := (b + a) / 2;
var fx := f(x);
if f(x) * f(a) > 0 then
begin
a := x;
fa := fx;
end
else
b := x;
end;
Лекция 8
Вложенные циклы
Метод последовательной детализации
Задача. Вывести все простые числа <= n
writeln(2);
x := 3;
while x <= n do
begin
Если число x — простое, то
writeln(x);
x += 2;
end;
Метод окаймления
Задача. Вывести Ak, A = 2..10
Метод окаймления заключается в том, что что мы окаймляем данный алгоритм внешним циклом, "размораживая" некоторый параметр.
Итак, пусть A — фиксировано( "заморожено" ).
var p := 1.0;
for var i:=1 to k do
p *= A;
write(p);
Теперь размораживаем A:
for A:=2 to 10 do
begin
...
end;
Переборные задачи
Класс задач, в которых требуется перебрать множество вариантов и выбрать несколько оптимальных по каким-то критериям.
Задача
- Дано равенство: a2 + b2 = c2, a,b,c — целые
- Вывести все такие тройки (a, b, c), что: a<=100, b<=1000, c<=1000;
Решение
for var a:=1 to 1000 do
for var b:=1 to 1000 do
for var c:=1 to 1000 do
if a*a + b*b = c*c then
writeln(a, b, c);
Однако, ясно, что
a2 + b2 = c2 <=> b2 + a2 = c2
Оптимизация
for var a:=1 to 1000 do
for var b:=1 to a-1 do
begin
var c := round(sqrt(a*a + b*b));
if a*a + b*b = c*c then
begin
writeln(a, b, c);
writeln(b, a, c);
end;
end;
Вывод. При наличии нескольких вложенных циклов нужно оптимизировать самый внутренний.
Ссылки
- [%D0%9E%D1%81%D0%B5%D0%BD%D0%BD%D0%B8%D0%B9_%D1%81%D0%B5%D0%BC%D0%B5%D1%81%D1%82%D1%80%3B_%D0%9C%D0%B8%D1%85%D0%B0%D0%BB%D0%BA%D0%BE%D0%B2%D0%B8%D1%87_%D0%A1.%D0%A1.%3B_2008%3B_II Вторая часть конспекта]
- Другие конспекты