Помогите, пожалуйста, доработать код.Думаю ошибок там много(((
program lab_a; {Описать класс, реализующий тип данных "вещественная матрица" и работу с ними.Методы класса должны обеспечивать: сложение, вычитание, умножение матриц (умножение, как на другую матрицу, так и на число); вычисление транспонированной матриц; проверку типа матрицы (квадратная, диагональная, нулевая, единичная); Написать программу, демонстрирующую работу с этим классом.}
{$APPTYPE CONSOLE}
uses SysUtils;
type veshmatr=class X:array of array of Double; n,m:integer;
Procedure vvod (var B:veshmatr); Procedure vivod ( var B:veshmatr); Procedure slosh(const A,B:veshmatr; var C:veshmatr); Procedure vichet(const A,B:veshmatr; var C:veshmatr); Procedure umnosh_na_chislo(const A:veshmatr; var B:veshmatr); Procedure umnosh_na_matr(const A,B:veshmatr; var C:veshmatr); Procedure transpan(const A:veshmatr;var B:veshmatr); Function TypematriX:string;{определяет тип матрицы:квадратная, диоганальная,нулевая или единичная} end;
var W,R,T:veshmatr; i,j,k:integer;
procedure veshmatr.vvod( var B:veshmatr); begin for i:=1 to n do for j:=1 to m do begin write('vvedite_element[',i,',',j,']=',''); readln(B.X[i,j]) end end;
Procedure veshmatr.vivod ( var B:veshmatr); begin for i:=1 to n do begin for j:=1 to m do writeln(' ',B.X[i,j]:12:3); writeln end;
end;
Procedure veshmatr.slosh(const A,B:veshmatr; var C:veshmatr); begin for I := 1 to n do for j := 1 to m do begin C.X[i,j]:=A.X[i,j]+B.X[i,j] end; end;
Procedure veshmatr.vichet(const A,B:veshmatr; var C:veshmatr); begin for I := 1 to n do for j := 1 to m do begin C.X[i,j] :=A.X[i,j]-B.X[i,j] end; end;
Procedure veshmatr.umnosh_na_chislo(const A:veshmatr; var B:veshmatr); var chislo:double; begin writeln('vvedite_chislo'); readln(chislo); for i:=1 to n do for j:=1 to m do begin B.X[i,j]:= A.X[i,j] * chislo end end;
Procedure veshmatr.umnosh_na_matr(const A,B:veshmatr; var C:veshmatr); var i,j,k:word; begin for i:=1 to n do for j:=1 to m do begin C.X[i,j]:=0; for k:=1 to n do C.X[i,j]:=C.X[i,j]+A.X[i,k]*B.X[k,j]; end; end;
Procedure veshmatr.transpan( const A:veshmatr;var B:veshmatr); var i,j:integer; begin for i:=1 to n do for j:=i to m do B.X[i,j]:=A.X[j,i]; end;
Function veshmatr.TypematriX:string; begin if n=m then writeln('matrica_kvadratnaya');
for i:=1 to n do for j:=1 to m do begin if (i<>j) and (X[i,j]=0) then writeln('matrica_diagonalnaya'); if X[i,j]=0 then writeln('matrica_nulevaya'); end;
for i:=1 to n do for j:=1 to m do if (i=j) and (X[i,j]=1) then writeln('matrica_edinichnaya')
Первая из них - неправильный выбор раздела. Тебе это надо сделать на Паскале, или Дельфи? А может быть, Object Pascal? Определись с этим, потом будем смотреть дальше.
Svetlana
16.09.2009 20:19
Object Pascal
volvo
16.09.2009 21:22
В таком случае вот тебе информация к размышлению:
type veshmatr=class X:array of array of Double; n,m:integer; Procedure vvod; Procedure vivod;
Constructor Create;
Procedure Add(const A: veshmatr); // self := self + A Procedure Sub(const A: veshmatr); // self := self - A Procedure Mult(f: double); // self := self * f Procedure Mult(const A: veshmatr); // self := self * A Procedure Transpose; // self := T(self) Function TypematriX: string; end;
Этого интерфейса в принципе достаточно, чтобы организовать тот класс, который тебе нужен. В Object Pascal-е есть перегрузка (overloading) функций, так что одно имя можно использовать для нескольких методов, при условии, что в них будут передаваться разные параметры (что я и сделал на примере Mult). Второе: обрати внимание, у тебя все время должен изменяться тот экземпляр, для которого вызван метод. Поэтому нет нужды передавать в качестве параметров исходную матрицу, и результат тоже. Только второй параметр - то, что находится справа от знака операции.
Еще одно: никогда не делай так, как пыталась сделать в методе umnosh_na_chislo (я про то, что ты внутри метода пытаешься заставить пользователя ввести само число, на которое надо умножить матрицу.) Этого делать нельзя ни в коем случае: метод занимается ТОЛЬКО перемножением матрицы на число. Всё, больше ничем. Он получает на вход ТОЛЬКО число, на которое надо умножить матрицу. Как и когда ты получаешь от пользователя это число - это твоя проблема, метод об этом знать ничего не должен, это не его дело. Его дело - получить матрицу и число, и перемножить их. Точка. Не пытайся возхложить на методы чужую работу. Каждый должен заниматься своим делом. Кто-то складывает, кто-то перемножает, кто-то вводит данные, кто-то выводит их. А не "все вперемешку".
Тему переношу в 32-битные компиляторы, там гораздо ближе к Object-Pascal-ю.
Дальше сама справишься?
Svetlana
16.09.2009 21:34
Спасибо,стало яснее. Только у меня ещё одна проблема:в первой же процедуре ввода. Она меня выбрасывает из командной строки после ввода первого элемента массива. Почему?
volvo
16.09.2009 21:43
Я не вижу у тебя нигде инициализации массива Х в классе... У тебя просто попытка записи в неинициализированную переменную. Напиши свой конструктор, в котором сделай SetLength этому массиву, тогда все будет работать. Только вот M, N надо бы знать ДО инициализации.
Svetlana
16.09.2009 21:45
Спасибо
Svetlana
14.10.2009 16:29
Решила написать работающий код(может кому-нибудь пригодится):
program lab_a; {Описать класс, реализующий тип данных "вещественная матрица" и работу с ними.Методы класса должны обеспечивать: -сложение, вычитание, умножение матриц (умножение, как на другую матрицу, так и на число); -вычисление транспонированной матриц; -проверку типа матрицы (квадратная, диагональная, нулевая, единичная); Написать программу, демонстрирующую работу с этим классом.}
{$APPTYPE CONSOLE}
uses SysUtils;
type veshmatr=class private{члены класса доступны только в этом модуле и внутри методов этого класса}
X:array of array of real; n,m:integer;
public {члены класса доступны из лююбой точке программы,где действует описание класса} Constructor Create; Procedure vvod (const A:veshmatr) ; Procedure vivod ( const A:veshmatr); Procedure Add (const A,B:veshmatr; var C:veshmatr); Procedure Sub(const A,B:veshmatr; var C:veshmatr); Procedure Mult(s: Double;const A:veshmatr;var B:veshmatr); overload; {один и тот же алгоритм для разных типов данных} Procedure Mult ( const A,B:veshmatr;var C:veshmatr); overload; Procedure Transpose( const A:veshmatr; var T:veshmatr); Function TypematriX:string;{определяет тип матрицы:квадратная, диоганальная,нулевая или единичная} end;
var M1,M2,M3,T:veshmatr; {это и есть объекты} s: Double; U:string; Ch:char;
Constructor veshmatr.Create;
begin inherited Create;{выполнение программы прерывается и вызывается одноименный метод родительского класса}
setlength(X,20,20); end;
procedure veshmatr.vvod( const A:veshmatr); var f,z,n,m:integer; begin write('vvedite_kol-vo_strok_N >>>_'); readln(n);
write('vvedite_kol-vo_stolbofff_M >>>_'); readln(m); for f:=0 to n-1 do for z:=0 to m-1 do begin write('vvedite_[',f,',',z,']','___'); readln(A.X[f,z]) end; for f:=0 to n-1 do begin {красивый ввод,похоже на матрицу} for z:=0 to m-1 do write(' ',A.X[f,z]:12:3); writeln end; writeln end;
Procedure veshmatr.vivod ( const A:veshmatr); var f,z:integer; begin writeln('Result:'); for f:=0 to n-1 do begin for z:=0 to m-1 do write(' ',A.X[f,z]:12:3); writeln end; writeln end;
Procedure veshmatr.Add(const A,B:veshmatr; var C:veshmatr); var f,z:integer; begin write('vvedite_kol-vo_strok_N >>>_'); readln(n);
write('vvedite_kol-vo_stolbofff_M >>>_'); readln(m); for f := 0 to n-1 do for z := 0 to m-1 do begin C.X[f,z]:=A.X[f,z]+B.X[f,z] end; {складываем две матрицы поэлементно} end;
Procedure veshmatr.Sub(const A,B:veshmatr; var C:veshmatr); var f,z:integer; begin write('vvedite_kol-vo_strok_N >>>_'); readln(n);
write('vvedite_kol-vo_stolbofff_M >>>_'); readln(m); for f := 0 to n-1 do for z:= 0 to m-1 do begin C.X[f,z] :=A.X[f,z]-B.X[f,z] end; {вычитаем две матрицы поэлементно} end;
Procedure veshmatr.Mult(s: Double;const A:veshmatr;var B:veshmatr); var f,z:integer; begin write('vvedite_kol-vo_strok_N >>>_'); readln(n);
for f:=0 to n-1 do for z:=0 to m-1 do T.X[f,z]:=A.X[z,f]; end;
Function veshmatr.TypematriX:string; var f,z:integer;flag,flag1:boolean; begin write('vvedite_kol-vo_strok_N >>>_'); readln(n);
write('vvedite_kol-vo_stolbofff_M >>>_'); readln(m); if n=m then writeln('matrica_kvadratnaya');
{_________проверка на диагональность___________} flag:=true;flag1:=false; {инициализация флагов} f:=0; while (f<=n-1) and (flag)do begin If X[f,f]=0 then flag :=false; If X[f,f]<>0 then flag1:=true; inc(f); end; if (not flag) then writeln('ne_diag'); f:=0; while (f<=n-1) and (flag1) do begin z:=0; while (z<=m-1) do begin if (f<>z) and (X[f,z]=0) then flag1:=true; if (f<>z) and (X[f,z]<>0)then flag1:=false;
inc(z);
end; inc(f); end; if flag1 then writeln('matr_diag');
{__________проверка на нулевую______________} flag:=true; f:=0; while (f<=n-1) and (flag) do begin z:=0; while z<=m-1 do begin if X[f,z]<>0 then flag:=false else flag:=true; inc(z); end; inc(f); end;
if flag then writeln('nulevaya');
{_______________проверка на единичную___________} flag:=true;flag1:=false; {инициализация флагов} f:=0; while (f<=n-1) and (flag)do begin If X[f,f]<>1 then flag :=false; If X[f,f]=1 then flag1:=true; inc(f); end; if (not flag) then writeln('ne_edinichnaya'); f:=0; while (f<=n-1) and (flag1) do begin z:=0; while (z<=m-1) do begin if (f<>z) and (X[f,z]=0) then flag1:=true; if (f<>z) and (X[f,z]<>0)then flag1:=false;
inc(z);
end; inc(f); end; if flag1 then writeln('matr_edinichnaya');
writeln('Add M1+M2? y/n >>>_');readln(ch); if ch='y' then begin M3.Add(M1,M2,M3); {вызов процедуры сложения} Writeln('__________Add_M1+M2________'); M3.vivod(M3) end;
writeln('Sub M1-M2? y/n >>>_');readln(ch); if ch='y' then begin M3.Sub(M1,M2,M3); {вызов процедуры вычитания} Writeln('__________Sub_M1-M2________'); M3.vivod(M3) end;
writeln('Mult s*M2? y/n >>>_');readln(ch); if ch='y' then begin writeln('vvedite_s'); readln(s); M3.Mult(s,M1,M3); Writeln('__________Mult_s*M1________'); M3.vivod(M3) end;
writeln('Mult M1*M2? y/n >>>_');readln(ch); if ch='y' then begin M3.Mult(M1,M2,M3); Writeln('__________Mult_M1*M2_______'); M3.vivod(M3) end;
writeln('Traspon M1? y/n >>>_');readln(ch); if ch='y' then begin T.Transpose(M1,T); Writeln('______Transponirovanaya____'); T.vivod(T) end;
writeln('Found type M1? y/n >>>_');readln(ch); if ch='y' then begin U:=M1.TypematriX; Writeln(U) end;
writeln('Found type M2? y/n >>>_');readln(ch); if ch='y' then begin U:=M2.TypematriX; Writeln(U) end;
M1.Free; {удаляем объект и переменная больше не ссылается на к.-л. обл.памяти} M1:=nil; M2.Free; M2:=nil; M3.Free; M3:=nil; T.Free; T:=nil; readln end.
volvo
14.10.2009 18:21
Что это было? Вот это тебе зачем, например:
Цитата
Procedure Add (const A,B:veshmatr; var C:veshmatr);
? Add - сам по себе метод класса veshmatr, так ты мало того, что не используешь возможность вернуть результат (почему процедура, а не функция?), так еще и не используешь self.X, а передаешь оба операнда как параметры... Зачем тогда делать "сложение" методом класса?
Зачем понадобилось в Transpose, например, заставлять пользователя вводить количество строк/столбцов? Что, класс не знает, сколько столбцов, а сколько строк в той матрице, которую он хранит? Знает (иначе зачем тебе M и N?). Почему для печати матрицы надо делать вот этот ужас:
Цитата
M3.vivod(M3)
, а не просто M3.vivod ?
В общем, эту программу можно значительно упростить и сделать работу с классом гораздо более ясной и понятной... Чуть позже покажу, как...
Svetlana
2.11.2009 18:23
Хорошо,буду ждать
volvo
3.11.2009 10:53
Ну вот. Сравни с твоей реализацией, и скажи, с чем удобнее работать? Можно и дальше улучшать, кстати, это еще не самый окончательный вариант. Если честно, я думал, ты сама уже все сделала - столько времени прошло.
program lab_a; {$APPTYPE CONSOLE} uses SysUtils;
type veshmatr = class private X: array of array of real; rows, cols: integer;
public constructor Create(ARows, ACols: integer); destructor Destroy;
procedure Vvod(); procedure Vivod();
function Add(const B: veshmatr): veshmatr; function Sub(const B: veshmatr): veshmatr; function Scale(f: double): veshmatr; function Mult(const B: veshmatr): veshmatr; function T: veshmatr; function TypematriX(): string; end;
procedure veshmatr.Vvod(); var iCols, iRows: integer; begin for iRows := 0 to Rows - 1 do for iCols := 0 to Cols - 1 do begin write('element [', iRows,',',iCols,'] = '); readln(X[iRows, iCols]) end; Vivod(); end;
procedure veshmatr.vivod(); var iCols, iRows: integer; begin if (Rows = 0) and (Cols = 0) then writeln('<empty>');
for iRows := 0 to Rows - 1 do begin for iCols := 0 to Cols - 1 do write(X[iRows, iCols]:12:3); writeln; end; end;
function veshmatr.Add(const B: veshmatr): veshmatr; var iCols, iRows: integer; begin if (Rows <> B.Rows) or (Cols <> B.Cols) then result := VeshMatr.Create(0, 0) else begin result := VeshMatr.Create(Rows, Cols); for iRows := 0 to Rows - 1 do for iCols := 0 to Cols - 1 do result.X[iRows, iCols] := X[iRows, iCols] + B.X[iRows, iCols]; end end;
function veshmatr.Sub(const B: veshmatr): veshmatr; var iCols, iRows: integer; begin if (Rows <> B.Rows) or (Cols <> B.Cols) then result := VeshMatr.Create(0, 0) else begin result := VeshMatr.Create(Rows, Cols); for iRows := 0 to Rows - 1 do for iCols := 0 to Cols - 1 do result.X[iRows, iCols] := X[iRows, iCols] - B.X[iRows, iCols]; end end;
function veshmatr.Scale(f: double): veshmatr; var iCols, iRows: integer; begin result := veshmatr.Create(Rows, Cols); for iRows := 0 to Rows - 1 do for iCols := 0 to Cols - 1 do result.X[iRows, iCols] := f * X[iRows, iCols];
end;
function veshmatr.Mult(const B: veshmatr): veshmatr; var i, j, k: integer; begin if (Cols <> B.Rows) then result := VeshMatr.Create(0, 0) else begin result := veshmatr.Create(Rows, B.Cols); for i := 0 to Rows - 1 do for j := 0 to B.Cols - 1 do begin result.X[i, j] := 0; for k := 0 to Cols - 1 do result.X[i, j] := result.X[i, j] + X[i, k] * B.X[k, j]; end end; end;
function veshmatr.T: VeshMatr; var iCols, iRows: integer; begin result := VeshMatr.Create(Cols, Rows); for iRows := 0 to Rows - 1 do for iCols := 0 to Cols - 1 do result.X[iCols, iRows] := X[iRows, iCols]; end;
function veshmatr.TypematriX(): string; var iCols, iRows: integer; flag_diag, flag_O, flag_E: boolean; begin result := '';
if (Rows = Cols) then result := result + 'square'#10#13;
for iCols := 0 to Cols - 1 do for iRows := 0 to Rows - 1 do begin flag_diag := flag_diag and ( ((iCols = iRows) and (X[iCols, iRows] <> 0)) or ((iCols <> iRows) and (X[iCols, iRows] = 0)) ); flag_O := (X[iCols, iRows] = 0); flag_E :=flag_E and ( ((iCols = iRows) and (X[iCols, iRows] = 1)) or ((iCols <> iRows) and (X[iCols, iRows] = 0)) ); end;
if flag_diag then result := result + 'diagonal'#10#13 else result := result + 'non-diagonal'#10#13; if flag_O then result := result + 'O-matrix'#10#13; if flag_E then result := result + 'E-matrix'#10#13; end;
function GetAnswer(s: string): boolean; var answer: char; begin write(s); readln(answer); result := answer in ['y', 'Y']; end;
if GetAnswer('Add M1 + M2? y/n >>>_') then begin Writeln('__________Add_M1+M2________'); with M1.Add(M2) do begin Vivod(); Destroy(); end; end;
if GetAnswer('Sub M1-M2? y/n >>>_') then begin Writeln('__________Sub_M1-M2________'); with M1.Sub(M2) do begin Vivod(); Destroy(); end; end;
if GetAnswer('Mult s*M1? y/n >>>_') then begin write('vvedite s: '); readln(s); Writeln('__________Mult_s*M1________'); with M1.Scale(s) do begin Vivod(); Destroy(); end; end;
if GetAnswer('Mult M1*M2? y/n >>>_') then begin Writeln('__________Mult_M1*M2_______'); with M1.Mult(M2) do begin Vivod(); Destroy(); end; end;
if GetAnswer('Traspon M1? y/n >>>_') then begin Writeln('______Transponirovanaya____'); with M1.T do begin Vivod(); Destroy(); end; end;
if GetAnswer('Found type of M1? y/n >>>_') then begin Writeln(M1.TypematriX()); end; if GetAnswer('Found type of M2? y/n >>>_') then begin Writeln(M2.TypematriX()); end;
M2.Destroy; M1.Destroy;
readln end.
Svetlana
3.11.2009 15:35
Ну вот. Сравни с твоей реализацией, и скажи, с чем удобнее работать?
Конечно же этот вариант лучше,причём намного
Если честно, я думал, ты сама уже все сделала - столько времени прошло.
На самом деле я сдала эту работу и совсем о ней не вспоминала...Спасибо
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.