Вступление
Здравствуйте! |
||||||||||||||||||||||||||
Программ'sЕдинственное, что я хочу сказать перед практикой, так это то, что предложенные решения не являются единственными. Итак в прошлый раз я не объяснил про полиндром. Вообщем это довольно простая програмка. Хотя, когда сталкиваешься с этим в первый раз, всё таки задумываешься. Вообщем основная мысль такая: мы пробегаем строку с начала и с конца одновременно, пока не встретимся. Если при этом символы, отстояшщие на равном растоянии от концов, не будут равны , значит слово не полиндром:
К сожалению в оригинальном выпуске в программе была допущенна ошибка. Правильный вариант программы приведён ниже:
Следующее задание, которое я не рассмотрел, посвященно переводу строки из заглавных букв в строчные. Давайте вспомним, что нам нужно сделать, для этого.
Теперь обратимся в сторону математики. Например займёмся тригонометрией. Стандартные функции языка такие:
function Sin(X: Real): Real; - возвращает sin угла х (в радианах).Если вы не владеете терминологией, то я скажу лишь кое-что. Остальное предоставим предподавателям математики. С sin и cos я предпологаю знакомы все. Итак тангенсом угла А называется выражение tg A = sin A / cos A Котангенсом называется выражение: ctg A = 1 / tg A = cos A / sin A Соответственно существуют обратные функции, которые по значению дадут нам угол. Эти функции имеют те же имена, но с приставкой arc (arccos, arcsin, arctg, arcctg). Многие ошибочно пологают, что раз называется обратная функция, то она равна 1 / функцию. Это не так. Давайте рассмотрим пример: пусть у нас есть два множества А и В:
Теперь посмотрим на наш скудный арсенал функций - всего 3 штуки.... мда. не густо. Но ведь язык Паскаль и был создан для обучения программированию. Вот сейчас мы и научимся считать любые тригонометрические функции. Думаю вы уже догадались, как можно сосчитать tg и ctg, если не догадались, то посмотрите ещё раз сюда. arcctg так же получается просто из arctg. Всё дело в том, что они связаны такой формулой: arctg A + arcctg A = П /2 (где П - число Пи = 3.141592653589). Поэтому получить из arctg arcctg несложно. Сложнее с arcsin и arccos. Они связаны между собой таким соотношением: arcsin A + arccos A = П / 2. Однако, как выразить arccos или arcsin через arctg я не знаю. Возможно такая формула и есть, возможно её нет. Мы будем исходить из другого. Конечно, то что будет написанно ниже будет понятно не всем, однако это математика (высшая, а не элементарная) и тут ничего не поделать. Итак ряд Тейлора. Если функция f (x) допускает в некоторой окрестности точки а разложение в степенной ряд по степеням х-а, то этот ряд имеет вид: f (x) = f (a) + f' (a) (x - a) + f'' (a) (x - a) 2 / 2! + ... + f(n) (a) (x - a) n / n! + ...где f(n) (a) - n-ая производная, вычисленная в точке а. n! - факторил n. при a = 0 получается ряд Маклорена, которым мы и будем пользоваться. Давайте напишем такой ряд для arcsin: x + 1/2 * x 3 / 3 + 1 / 2 * 1 / 3 * x5 / 5 + ... + (1 * 3 * 5* .... *(2n - 1) / (2 * 4 * 6 *....*2n) * x 2n + 1 / (2n + 1)для того, что бы подсчитать arcsin для угла Х, нам надо вычислить эту сумму. Так же естественно, что до бесконечности мы считать её не можем, поэтому считать нужно до какого-то n-ого члена. Чем больше будет это n, тем точнее будет подсчитан arcsin.
Так как мы можем разложить в ряд Тейлора любую функцию, то подсчёт этой функции не составит для вас никакого труда. Следующая задача, называется задачей о Ханойских башнях. Пусть у нас имеется 3 стержня (назовём их X, Y, Z) и N дисков. Наденем все диски на стержень Х в порядке возрастания: в самом низу окажется самый большой диск, в верху самый маленький. Задача состоит в том, что бы перенести эти диски со стержня Х на стержень Y (в том же порядке). Использовать при этом можно только стержень Z. За один раз можно переносить только один диск. Любой диск можно разместить либо на пустом стержне, либо поверх диска большего размера (соответственно вверху всегда должны быть маленькие диски). В решении этой задачи нам поможет рекурсия. Рекурсия - это вызов подпрограммы саму себя. Например, программа для спуска по лестнице :) варианты реализации:
подождите запускать эту программу !!! посмотрите на процедуру demo - мы вызываем саму себя, но нигде нет выхода... кажется это что-то типа цикла while 1 do ... будет выполняться вечно, но давайте запустим.... ждём .... оба-на вылазит сообщение Error 202: Stack overflow error. вот вам и вечный вызов :) Что это такое? Пока создам примитивную картинку: есть специальная область памяти (называется стек - Stek) вот её мы и переполнили :) Просто в неё кладётся кое-какая информация о вызове процедур и вызывая процедуру саму из себя, мы постепенно занимаем эту память (освобождается она при выходе из процедуры)... вот как только мы забьём всё что можно и вылазит сообщение об ошибке. Можете убедится, что мы не освобождаем эту память, т.к. не доходим до слова end (жмите F7, если забыли. Глубиной рекурсии называется количество вызовов процедуры(функции) саму себя. В предыдущем примере, мы превысили допустимо возможную глубину и были наказаны ошибкой 202. Так вот для решения задачи о ханойских башнях нам понадобится рекурсия. Лучшим вариантом будет, если вы возьмёте ручку и бумагу и нарисуете 3 палки (это X, Y, Z :) и на Х поставите 3 чёрточки разных размеров. Это башни :) Так вот я сейчас буду объяснять, как решить такую задачу, а вы для наглядности рисуйте. Диски нумеруем так: самый верхний - 1, самый средний 2, самый нижний - 3.
Сначала перенесём диск 1 с Х на Y. поупражнявшись с несколькими башнями можно прийдти к такому алгоритму:
Вот пример реализации этой задачи:
обратите внимание, что парметры передаются в процедуру таким образом: количество дисков - n, x - ось с которой мы перкладываем диски, y - ось на которую мы перекладывам диски, z - ось временное хранилище. Поэтому для реализации алгоритма нам нужно выполнить такие действия:
Отвлечёмся ещё на теорию: рекурсия может быть неявной. Например такой: procedure A; begin ..... B; ........ end; procedure B; begin ......... A; ...... end;Постойте, а откуда компилятор узнает о существовании процедуры B ? Откуда, откуда - от нас :) мы должны сказать компилятору, что типа нечего волноваться, функция описана где-то там, а вот тебе её название, что б случайно не попутался :) Делается с помощью директивы forward, которая и говрит эту фразу компилятору. Директива пишется сразу после описания процедуры (функции). Рассмотрим пример из help'a к Паскалю:
Давайте знакомится с халявой Паскаля - обратите внимание на это:
|
||||||||||||||||||||||||||
ПослесловиеНу вот практика и кончилась. Конечно рассмотреть большое множество задач нам не удасться. Поупражняйтесь в рекурсии. Это пригодится. Вот кстати и очередное задание, для тех кто его делает, - написать функцию для вычисления факториала с помощью рекурсии. На этом всё. На следующей неделе увидимся чаще! |