Программирование. Модуль GRAPH. Модульное и объектное программирование. Учебно-методическое пособие
.pdf
|
81 |
|
|
For I:=1 To M Do |
|
|
Komp^[I]:=A*Komp^[I] ; |
|
End; |
|
|
{------------ |
Метод – скалярное умножение двух векторов---------------- |
} |
Procedure Vector.Product; Var I:Integer;
Begin
S:=0;
For I:=1 To M Do S:=S+V1.Komp^[i]*V2.Komp^[i];
S:=S;
End;
End.
Текст файла использующий разработанный модуль MVECTOR.TPU.
Program ZAD_3;
Uses Crt,MVector;{- подключение модулей} Var
A,B,C:Vector; {- экземпляры-переменные объектного типа - вектора}
S:Real;
{---------------------ОСНОВНАЯ ПРОГРАММА---------------------------} Begin
ClrScr; {- очистка экрана}
A.Init(3);{- инициализация поля вектора A: количество компонент – три} B.Init(3);{- инициализация поля вектора B: количество компонент – три} C.Init(3);{- инициализация поля вектора C: количество компонент – три} Writeln('Ввод элементов вектора A:');
A.Scanf;
Writeln(‘Ввод элементов вектора B:');
B.Scanf;
Writeln('Компоненты вектора C=A+B:');
C.Sum(A,B); |
|
C.Printf; |
{- вывод компонент вектора C} |
writeln; |
|
A.Product(A,B,S);{- скалярное произведение векторов A и B} writeln('Скалярное произведение векторов A*B=',S:5:3);
Writeln('Умножение 3*A:'); A.Mul(3);
A.Printf;
A.Delete;
B.Delete;
C.Delete;
Writeln;
82
Writeln(‘Освобождения ОП от компонент вектора C');
C.Printf;
End.
Пример 4. На основе объекта Vector (Вектор) создать производный объект Matrix (Матрица) для работы с действительной матрицей. В объекте должны быть представлены поля: количество строк матриц, количество столбцов матриц, элементы действительной матрицы. Реализовать методы: сложение двух матриц, умножение матрицы на действительное число, перемножение двух матриц.
Операции над матрицами:
1. |
Сложение матриц: если |
, |
, то A |
B будет матрица |
||
|
, где |
. |
|
|
|
|
2. |
Умножение матрицы на действительное число: если |
, то |
A |
|||
будет матрица |
, где |
|
. |
|
|
|
3. |
Перемножение двух матриц: если |
|
, |
, то A B будет |
||
матрица |
, где |
. |
|
|
|
|
Поле – элементы действительной матрицы определим с помощью указателя на одномерный массив, что позволит сформировать двумерный динамический массив. Для этого надо применять в качестве индекса массива выражение над номерами матриц – строк и столбцов.
Обращение к A[i,j] – элементам двумерного массива производится с помощью индексов-выражений, определяющих положение элемента в одномерном массиве такого же размера:
(i-1)*N+j
где N – количество элементов в столбце;
i– номер требуемой строки;
j– номер элемента в требуемой строке;
(i-1)*N – количество элементов в полных строках, расположенных до требуемой строки;
(i-1)*N+j – номер элемента двумерного массива в одномерном динамическом массиве.
Схематично для N=3 взаимосвязь элементов одномерного и двумерного массивов представлена на рис. 1.
Рис.1. Взаимосвязь элементов одномерного и двумерного массива
83
Сформируем модуль, где будет храниться тип-объект Matrix производный от типа-объекта Vector, и тестирующую программу.
Текст PAS- файла модуля:
{$R-} {- отключение контроля границ массива} |
|
|
Unit MMatrix; {- имя модуля} |
|
|
{---------------- |
Интерфейсная часть модуля-------------------------- |
} |
Interface |
|
|
Uses Crt,MVector;
Type
Matrix=Object(Vector) {Объект матрица(потомок объекта вектор):}
|
N:Integer; {- количество столбцов матрицы} |
|
|
Procedure Init(A,B:Integer); {- метод инициализации} |
|
|
Procedure Scanf; {- метод - ввод элементов матрицы} |
|
|
Procedure Printf; {- метод - вывод элементов матрицы} |
|
|
Procedure Delete; {- метод - обнуление указателя} |
|
|
Procedure Sum(M1,M2:Matrix); |
|
|
Procedure Mul(A:Integer); |
|
|
Procedure Product(M1,M2:Matrix); |
|
|
End; |
|
{----------------- |
Исполняемая часть модуля--------------------------- |
} |
Implementation |
|
|
{-------------------- |
Метод инициализации----------------------------- |
} |
Procedure Matrix.Init; |
|
|
Begin |
|
|
|
M:=A;N:=B; { M - количество строк матрицы, N – количество |
|
столбцов} |
|
|
|
GetMem(Komp,M*N*SizeOf(Real)); {- выделение ОП для Komp^} |
|
End; |
|
|
{------------ |
Метод – ввод элементов матрицы с клавиатуры------------ |
} |
Procedure Matrix.Scanf; |
|
|
Var I,J,T:Integer;
Begin
T:=WhereY;
GoToXY(2,T);
For I:=1 To M Do
Begin
GotoXY(1,T+I+1);
Write(I:2);
End;
For J:=1 To N Do
Begin
GoToXY(J*6+2,T);
|
84 |
|
|
Write(J); |
|
|
End; |
|
|
For I:=1 To M Do |
|
|
For J:=1 To N Do |
|
|
Begin |
|
|
GoToXY(J*6+2,T+I+1); |
|
|
Read(Komp^[(I-1)*N+J]); |
|
|
End; |
|
End; |
|
|
{----------------Метод – вывод элементов вектора на экран------------} |
|
|
Procedure Matrix.Printf; |
|
|
Var I,J:Integer; |
|
|
Begin |
|
|
|
If Komp=Nil Then |
|
|
Begin |
|
|
Writeln('Не заданы элементы матрицы'); |
|
|
Exit; |
|
|
End; |
|
|
For I:=1 To M Do |
|
|
Begin |
|
|
For J:=1 To N Do |
|
|
Write(Komp^[(I-1)*N+J]:10:3); |
|
|
WriteLn; |
|
|
End; |
|
End; |
|
|
{---------- |
Метод – освобождение ОП для поля элементов матрицы--------- |
} |
Procedure Matrix.Delete; |
|
|
Begin |
|
|
|
FreeMem(Komp,M*N*SizeOf(Real)); {- освобождение ОП Komp^} |
|
|
Komp:=Nil; {- обнуление указателя} |
|
End; |
|
|
{------------------ |
Метод – сумма двух матриц-------------------------- |
} |
Procedure Matrix.Sum; |
|
|
Var I,J:Integer;
Begin
|
For I:=1 To M Do |
|
|
For J:=1 To N Do |
|
|
Komp^[(I-1)*N+J]:=M1.Komp^[(I-1)*N+J]+M2.Komp^[(I- |
|
|
1)*N+J]; |
|
End; |
|
|
{--------- |
Метод – умножение матрицы на действительное число----------- |
} |
Procedure Matrix.Mul; |
|
|
Var I,J:Integer; |
|
|
85
Begin
|
For I:=1 To M Do |
|
|
For J:=1 To N Do |
|
|
Komp^[(I-1)*N+J]:=A*Komp^[(I-1)*N+J] ; |
|
End; |
|
|
{--------------------- |
Метод –умножение двух матриц-------------------- |
} |
Procedure Matrix.Product;
Var I,J,K:Integer; S:Real;
Begin
For I:=1 To M1.M Do
Begin
For K:=1 To M2.N Do
Begin
S:=0;
For J:=1 To M1.N Do
S:=S+M1.Komp^[(I-1)*M1.N+J]*M2.Komp^[(J-1)*M2.N+K];
Komp^[(I-1)*M2.N+K]:=S;
End;
End;
End;
End.
Текст файла использующий разработанный модуль MMATRIX.TPU.
Program ZAD_4;
Uses Crt,MMatrix; {- подключение модулей} Var
A,B,C,D:Matrix; {- экземпляры-переменные объектного типа - матрица}
{--------------------- |
ОСНОВНАЯ ПРОГРАММА |
---------------------------} |
Begin |
|
|
ClrScr; |
{- очистка экрана} |
|
A.Init(3,3); {- инициализация полей матрицы A: строк – 3, столбцов-3} B.Init(3,3); {- инициализация полей матрицы B: строк – 3, столбцов-3} C.Init(3,3); {- инициализация полей матрицы C: строк – 3, столбцов-3} D.Init(3,3); {- инициализация полей матрицы D: строк – 3, столбцов-3} Writeln('Ввод элементов матрицы A:');
A.Scanf;
Writeln('Ввод элементов матрицы B:');
B.Scanf;
writeln('C=A+B:');
C.Sum(A,B);
C.Print; {- вывод элемента матрицы C} writeln('D=A*B:');
D.Product(A,B);
86
D.Print;
writeln('A*3=');
A.Mul(3);
A.Print;
Writeln('Delete A,B,C,D'); A.Delete;
B.Delete;
C.Delete;
D.DElete;
D.Print;
End.
Пример 5. Создать базовый объект Vector (Вектор) с виртуальными методами вычисления нормы для произвольного n-мерного вектора. Создать производный объект Matrix (Матрица) со своими методами вычисления нормы.
|
|
|
|
|
|
|
|
|
|
Нормы для произвольного вектора x (x1 , x2 ,..., xn ) из Rn : |
||||||||||||||||||
1) |
|
x |
|
|
|
|
|
|
|
max |
|
xi |
|
|
(норма - максимум); |
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
i (1, ,n) |
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
|
|
||
2) |
|
x |
|
|
|
|
2 |
|
|
|
|
xi2 |
(евклидова - норма); |
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
i 1 |
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3) |
|
x |
|
|
|
|
1 |
|
|
|
|
xi |
(норма - суммы). |
|
||||||||||||||
|
|
|
|
|
|
|
|
i 1 |
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
Нормы матрица |
определяются равенствами: |
|||||||||||||||||
1) |
|
A |
|
|
|
|
|
|
max |
n |
|
|
aij |
|
(норма - максимум); |
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
i (1, ,m) j |
1 |
|
|
|
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m n |
|
2 |
|
|
|
|
|
|
|
|
|||
2) |
|
A |
|
|
|
|
|
|
|
|
|
|
|
a |
|
|
(евклидова - норма); |
|||||||||||
|
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
ij |
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
i 1 j 1 |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
3) |
|
A |
|
|
|
|
1 |
|
max |
m |
|
|
aij |
|
(норма - суммы). |
|||||||||||||
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
j |
|
(1, ,n) i 1 |
|
|
|
|
|
|
|
|
|||||||
Листинг программы для решения поставленной задачи:
Program ZAD_5; {$R-}
Uses Crt; Type
TArray=Array[1..1] of Real; PArray=^TArray; Vector=Object
M:Integer;
Komp:PArray;
Constructor Init(A:Integer); Procedure Scanf; Procedure Printf;
87
Procedure Delete;
Function Norma_M:Real;Virtual; {- норма максимум} Function Norma_E:Real;Virtual; {- евклидова норма}
Function Norma_S:Real;Virtual; {- норма сумма} End;
Matrix=Object(Vector)
N:Integer;
Constructor Init(A,B:Integer); Procedure Scanf;
Procedure Print;
Procedure Delete;
Function Norma_M:Real;Virtual;
Function Norma_E:Real;Virtual;
Function Norma_S:Real;Virtual;
|
End; |
|
{---------------- |
Методы объекта - вектор--------------------------- |
} |
{-------------- |
Инициализация полей объекта------------------------- |
} |
Constructor Vector.Init; |
|
|
Begin |
|
|
|
M:=A; |
|
|
GetMem(Komp,M*SizeOf(Real)); |
|
End; |
|
|
{------------------ |
Метод – ввод элементов вектора------------------- |
} |
Procedure Vector.Scanf; |
|
|
Var I:Integer; |
|
|
Begin |
|
|
|
For I:=1 To M Do |
|
|
Read(Komp^[I]); |
|
End; |
|
|
{----------------- |
Метод – вывод элементов вектора------------------- |
} |
Procedure Vector.Print;
Var I:Integer;
Begin
|
If Komp=Nil Then |
|
|
Begin |
|
|
Writeln('Не заданы элементы вектора'); |
|
|
Exit; |
|
|
End; |
|
|
For I:=1 To M Do |
|
|
Write(Komp^[I]:7:3); |
|
End; |
|
|
{--------- |
Метод – освобождение ОП для поля элементов вектора |
--------} |
Procedure Vector.Delete; |
|
|
Begin |
|
|
|
FreeMem(Komp,M*SizeOf(Real)); |
|
|
Komp:=Nil; |
|
End; |
|
|
{----------------- |
Метод – норма-максимум вектора-------------------- |
} |
Function Vector.Norma_M; |
|
|
Var I:Integer; Max:Real; |
|
|
|
88 |
|
Begin |
|
|
|
Max:=Abs(Komp^[1]); |
|
|
For I:=2 To M Do |
|
|
If Max<Abs(Komp^[I]) Then |
|
|
Max:=Abs(Komp^[i]); |
|
|
Norma_M:=Max; |
|
End; |
|
|
{---------------- |
Метод – евклидова - норма вектора------------------- |
} |
Function Vector.Norma_E; |
|
|
Var I:Integer; S:Real; |
|
|
Begin |
|
|
|
S:=0; |
|
|
For I:=1 To M Do |
|
|
S:=S+Sqr(Komp^[i]); |
|
|
Norma_E:=Sqrt(S); |
|
End; |
|
|
{----------------- |
Метод – норма-сумма вектора------------------------ |
} |
Function Vector.Norma_S; |
|
|
Var I:Integer; S:Real; |
|
|
Begin |
|
|
|
S:=0; |
|
|
For I:=1 To M Do |
|
|
S:=S+Abs(Komp^[i]); |
|
|
Norma_S:=S; |
|
End; |
|
|
{---------------- |
Методы объекта - вектор--------------------------- |
} |
{-------------- |
Инициализация полей объекта------------------------- |
} |
Constructor Matrix.Init; |
|
|
Begin |
|
|
|
M:=A;N:=B; |
|
|
GetMem(Komp,M*N*SizeOf(Real)); |
|
End; |
|
|
{------------------ |
Метод – ввод элементов матрицы------------------- |
} |
Procedure Matrix.Scanf; |
|
|
Var I,J,T:Integer;
Begin
T:=WhereY;
GoToXY(2,T);
For I:=1 To M Do
Begin
GotoXY(1,T+I+1);
Write(I:2);
End;
For J:=1 To N Do
Begin
GoToXY(J*6+2,T);
Write(J);
End;
For I:=1 To M Do
For J:=1 To N Do
89
Begin
GoToXY(J*6+2,T+I+1);
Read(Komp^[(I-1)*N+J]);
End;
End;
{-----------------Метод – вывод элементов матрицы-------------------}
Procedure Matrix.Printf; |
|
|
Var I,J:Integer; |
|
|
Begin |
|
|
|
If Komp=Nil Then |
|
|
Begin |
|
|
Writeln('Не заданы элементы матрицы'); |
|
|
Exit; |
|
|
End; |
|
|
For I:=1 To M Do |
|
|
Begin |
|
|
For J:=1 To N Do |
|
|
Write(Komp^[(I-1)*N+J]:10:3); |
|
|
WriteLn; |
|
|
End; |
|
End; |
|
|
{--------- |
Метод – освобождение ОП для поля элементов матрицы |
--------} |
Procedure Matrix.Delete; |
|
|
Begin |
|
|
|
FreeMem(Komp,M*N*SizeOf(Real)); |
|
|
Komp:=Nil; |
|
End; |
|
|
{----------------- |
Метод – норма-максимум матрицы-------------------- |
} |
Function Matrix.Norma_M; |
|
|
Var I,J:Integer; S,Max:Real; |
|
|
Begin |
|
|
|
Max:=-1; |
|
|
For I:=1 To M Do |
|
|
Begin |
|
|
S:=0; |
|
|
For J:=1 To N Do |
|
|
S:=S+Abs(Komp^[(I-1)*N+J]); |
|
|
If Max<S Then Max:=S; |
|
|
End; |
|
|
Norma_M:=Max; |
|
End; |
|
|
{---------------- |
Метод – евклидова - норма матрицы------------------ |
} |
Function Matrix.Norma_E;
Var I,J:Integer; S:Real;
Begin
S:=0;
For I:=1 To M Do
For J:=1 To N Do
S:=S+Sqr(Komp^[(I-1)*N+J]) ;
Norma_E:=Sqrt(S);
|
90 |
|
End; |
|
|
{----------------- |
Метод – норма-сумма матрицы------------------------ |
} |
Function Matrix.Norma_S; |
|
|
Var I,J:Integer; S,Max:Real; |
|
|
Begin |
|
|
|
Max:=-1; |
|
|
For J:=1 To N Do |
|
|
Begin |
|
|
S:=0; |
|
|
For I:=1 To M Do |
|
|
S:=S+Abs(Komp^[(I-1)*N+J]); |
|
|
If Max<S Then Max:=S; |
|
|
End; |
|
|
Norma_S:=Max; |
|
|
End; |
|
Var
V:Vector; M:Matrix;
{---------------------ОСНОВНАЯ ПРОГРАММА----------------------------} Begin
Clrscr;
V.Init(3);
Writeln('Ввод элементов вектора V:'); V.Scanf;
Writeln('Норма-максимум вектора, Norma_M=',V.Norma_M:5:3); Writeln('Евклидова - норма вектора, Norma_E=',V.Norma_E:5:3);
Writeln('Норма - сумма вектора, Norma_S=',V.Norma_S:5:3); Writeln;
M.Init(3,3);
Writeln('Ввод элементов матрицы M:'); M.Scanf;
Writeln(' Норма-максимум матрицы, Norma_M=',M.Norma_M:5:3);
Writeln(' Евклидова - норма матрицы, Norma_E=',M.Norma_E:5:3);
Writeln(' Норма - сумма vfnhbws, Norma_S=',M.Norma_S:5:3); Writeln;
Writeln(' Удаление элементов вектора и матрицы из ОП:');
V.Delete;
M.Delete;
V.Printf;
M.Printf;
Readkey;
End.
