Сегодняшнее наше занятие, уважаемые подписчики, – последнее из посвящённых ветвлениям. Как и прежде, мы будем активно использовать модуль Problem.
Чем же мы будем заниматься потом? Конечно же, циклами! Кроме того, нам необходимо будет закрыть имеющиеся пробелы в изучении операторов ввода-вывода, а также поближе познакомиться со средствами ИСП для отладки программ.
И ЕЩЁ ПАРА ЗАДАЧ НА ВЕТВЛЕНИЯ
1. Решение задачи “Упорядочение”.
Задача V.3.1. “Упорядочение”. Заданы произвольные числа A и B. Построить подпрограмму упорядочения их по возрастанию.
Упорядочение двух чисел – простейшая из задач упорядочения. Но даже и в этом случае сначала придётся решить принципиальный вопрос, при каких условиях числа можно считать упорядоченными по возрастанию? Если числа разные, то ответ очевиден: последующее число должно быть больше предыдущего. Например, 5 и 7. Но как быть, если числа равны между собой? О каком возрастании может идти речь? Может быть, считать,
что в этом случае задача не имеет решения?
Последнее предположение вызывает беспокойство. Ведь мы должны стремиться строить алгоритмы, которые решают свои задачи при как можно меньшем количестве ограничений.
И тут на помощь, как всегда, приходит договорённость: числа будем считать упорядоченными по возрастанию, если каждое последующее число не меньше предыдущего. Математик такие числа назвал бы упорядоченными по неубыванию. И был бы прав. Но, не будем спорить о терминах. Аналогичная договорённость может быть сформулирована и в отношении упорядочения по убыванию: каждое последующее число должно быть не больше предыдущего. Из этого следует, что, во-первых, последовательность произвольных чисел можно упорядочить всегда, и во-вторых, последовательность одинаковых чисел может считаться упорядоченной как по возрастанию, так и по убыванию.
Всё вышесказанное относится к упорядочению числовых констант. А как быть с переменными? Для упорядочения переменных в принципе существуют две возможности.
Во-первых, можно переставлять местами сами переменные. Например, если A=10 и B=5, то записав переменные в порядке B, A, можно утверждать, что они упорядочены по возрастанию. Однако, такой способ упорядочения скрывает практически неразрешимую проблему: каким образом в качестве результата
работы подпрограммы можно зафиксировать иной порядок следования переменных?
Во-вторых, можно переставлять местами значения переменных. Порядок следования самих переменных при этом остаётся неизменным. Например, если A=10 и B=5, то обменяв их значения и получив A=5 и B=10, можно утверждать, что нам удалось упорядочить их значения по возрастанию. Реализовать способ
такого обмена можно достаточно просто.
Таким образом, у нас не остаётся выбора: упорядочивать переменные мы будем посредствомобмена их значений при фиксированном порядке следования.
Для обмена значений переменных A и B воспользуемся подпрограммой L.1.3 (процедура Exchange), изученной в материалах занятия 13. К этой подпрограмме обращение должно выполняться в том случае, если A > B, то есть значения переменных не упорядочены по возрастанию.
Поставленную задачу решает подпрограмма Regulate. В ней одни и те же переменные A и B выступают как в качестве исходных данных, так и в качестве результатов, то есть обе должны быть оформлены как Var-параметры. Это вполне естественно, так как в результате обмена значения обеих переменных могут быть изменены. По этой же причине подпрограмму
целесообразно оформить в виде процедуры. Процедура Regulate может быть легко модифицирована для упорядочения по убыванию заменой знака “ > “ знаком “ < “.
Процедура Regulate имеет вид:
ProcedureRegulate ( VarA, B: T ); Begin IfA > BThenExchange ( A, B ) End;
В таком виде процедура может использоваться для упорядочения переменных любого типа. Необходимо только в программе предварительно оформить соответствующий раздел типов, например, Type T=Real. Кроме того, в программе необходимо разместить также и саму вспомогательную процедуру Exchange.
Если же необходимо упорядочивать переменные типа Integer, то для этого можно воспользоваться процедурой Exchange, размещённой в модуле Problem http://a-morgun.narod.ru/a08-01/a0008-0001-0002.html. В этом случае программа решения задачи будет иметь следующий вид:
{$B+,D+,E+,I+,L+,N+,Q+,R+,X-} Program V_03_01; Uses Problem; Type T=Integer; Procedure Regulate ( Var A, B: T ); Begin If A > B Then Exchange ( A, B ) End; Var A,B: T; Begin Write('Введите числа A и B: '); ReadLn(A,B); Regulate ( A, B ); WriteLn( 'Числа упорядочены: A = ', A, ', B = ', B ) End.
2. Решение задачи “Пересечение прямых”.
Задача V.3.7. “Пересечение прямых”. Построить подпрограмму, которая определяет взаимное положение двух заданных прямых на плоскости, а также координаты точки пересечения, если они пересекаются. Известно, что каждая прямая проходит через две несовпадающие точки: первая – через точки (x1,y1) и (x2, y2), вторая – через точки (x3,y3) и (x4,y4).
С геометрической точки зрения две прямые на плоскости могут пересекаться (естественно, в одной точке), могут совпадать и могут быть параллельными.
Если прямые пересекаются, то координаты точки пересечения можно вычислить, решая совместно уравнения этих прямых. Однако, известно (см. материалы занятия 34), что при решениии системы двух линейных уравнений с двумя неизвестными возможно не только единственное решение. Решения могут отсутствовать, их также может быть бесчисленное множество. В приложении к прямым на плоскости отсутствие решений системы
означает, что прямые параллельны, а в случае бесчисленного множества решений системы имеем соответственно совпадение прямых.
Таким образом, для определения взаимного положения двух прямых на плоскости мы должны решать систему двух линейных уравнений с двумя неизвестными. Для этого можно воспользоваться процедурой V.2.7System_Equation (см. материалы занятия 34). При этом каждое линейное уравнение в составе системы должно представлять собой уравнение соответствующей прямой в виде A*x + B*y = C.
В свою очередь, коэффициенты уравнения каждой прямой A*x + B*y + C = 0 можно получить с помощью процедуры L.1.7Line, исходя из значений координат двух несовпадающих точек, через которые она проходит (см. материалы занятия 13). Обратившись к ней дважды, получим значения коэффициентов уравнений обоих прямых, обозначив их
A1, B1, C1 и A2, B2, C2 соответственно. В свою очередь, эти коэффициенты используются при обращении к процедуре System_Equation. При этом у коэффициентов C1 и C2 знак следует изменить на обратный, так как они соответствуют свободным членам системы уравнений,
в которой каждое уравнение имеет вид A*x + B*y = C.
Решение рассмотренной задачи оформлено в виде процедуры CrossLine.
Procedure CrossLine(x1,y1,x2,y2,x3,y3,x4,y4:Real; Var x,y:Real; Var z:Byte); Var A1,B1,C1,A2,B2,C2: Real; Begin Line(x1,y1,x2,y2,A1,B1,C1); Line(x3,y3,x4,y4,A2,B2,C2); System_Equation(A1,B1,-C1,A2,B2,-C2,x,y,z); End;
Исходными данными процедуры CrossLine являются координаты несовпадающих точек (x1, y1) и (x2, y2), через которые проходит первая прямая, и несовпадающих точек (x3, y3) и (x4, y4), через которые проходит вторая прямая. Результатами процедуры являются координаты возможной точки пересечения (x, y),
а также флажок z, значения которого совпадают со значениями флажка, получаемого при решении системы. При этом смысл значений флажка изменяется так, как оговаривалось выше.
{$B+,D+,E+,I+,L+,N+,Q+,R+,X-} Program V_03_07; Uses Problem;
Procedure CrossLine(x1,y1,x2,y2,x3,y3,x4,y4:Real; Var x,y:Real; Var z:Byte); Var A1,B1,C1,A2,B2,C2: Real; Begin Line(x1,y1,x2,y2,A1,B1,C1); Line(x3,y3,x4,y4,A2,B2,C2); System_Equation(A1,B1,-C1,A2,B2,-C2,x,y,z); End; Var x1,y1,x2,y2,x3,y3,x4,y4,x,y: Real; z: Byte; Begin Write('Введитекоординатыточекx1,y1,x2,y2: '); ReadLn(x1,y1,x2,y2); Write('Введитекоординатыточекx3,y3,x4,y4: '); ReadLn(x3,y3,x4,y4); CrossLine(x1,y1,x2,y2,x3,y3,x4,y4,x,y,z); Case z Of 1: WriteLn('Прямыепересекаютсявточке (',x:0:4,', ',y:0:4,')'); 2: WriteLn('Прямыесовпадают'); 3: WriteLn('Прямыепараллельны'); End End.
Уважаемые подписчики!При необходимости задать вопрос, проконсультироваться, уточнить или обсудить что-либо обращайтесь через Гостевую книгу моего персонального сайта http://a-morgun.narod.ru. При этом настоятельно рекомендую пользоваться браузером Internet Explorer.