logo
Работа с двумерными числовыми массивами

Выводы

Двумерный динамический массив - очень удобная конструкция для представления матрицы, размеры которой во время написания программы не известны. Но при его использовании нужно быть осторожным и учитывать некоторые особенности:

· При вызове SetLength с одним параметром размера будет выделена память только под первую размерность массива (например, будет увеличено число строк в матрице), остальные размерности затронуты не будут (в каждой добавленной строке будет ноль элементов).

· Каждый подмассив многомерного массива может иметь свою размерность (например, каждая строка матрицы в общем то может иметь длину, отличную от других)

· Необходимо всегда знать границы каждой размерности, чтобы не выйти за пределы массива в чужую память. Для этого полезны функции low и high.

· Необходимо всегда освобождать динамически выделенную память.

· При присваивании динамических массивов копирования данных не происходит, присваиваются лишь указатели, таким образом, после присваивания два массива будут указывать на одну и ту же область памяти. Чтобы получить копию массива, можно использовать функцию Copy.

· Copy копирует не весь многомерный массив, но только его первую размерность.

Приложения

Приложение 1. Тестовые примеры

Тест 1: Квадратная матрица 5x5.

Исходная матрица:

-100 -50 -20 0 20

50 100 200 1000 2000

4000 10000 20000 40000 80000

100000 -100000 -40000 -10000 -4000

-1000 -200 -20 2 12

Результат выполнения первого задания:

Максимальные элементы по строкам: 20; 2000; 80000; 100000; 12

Столбцы с максимальными элементами: 5; 5; 5; 1; 5

Результат выполнения второго задания:

S1 = 130

S2 = -40218

S1 > S2, матрица не была изменена

Результат выполнения третьего задания:

Число столбцов нечётно - был произведён сдвиг «вниз»

-1000 -200 -20 2 12

-100 -50 -20 0 20

50 100 200 1000 2000

4000 10000 20000 40000 80000

100000 -100000 -40000 -10000 -4000

Результат выполнения четвёртого задания:

Матрица, «развёрнутая» против часовой стрелки: -100; 50; 4000; 100000; -1000; -200; -20; 2; 12; -4000; 80000; 2000; 20; 0; -20; -50; 100; 10000; -100000; -40000; -10000; 40000; 1000; 200; 20000

Результат выполнения пятого задания:

Строки отсортированы в невозрастающем порядке сумм:

4000 10000 20000 40000 80000

50 100 200 1000 2000

-100 -50 -20 0 20

-1000 -200 -20 2 12

100000 -100000 -40000 -10000 -4000

Тест 2: прямоугольная матрица 3x8.

Исходная матрица:

1 - 18 17 -16 15 -14 13 -12

-2 19 20 2000 200000 20000000 2000000000 11

3 -4 5 -6 7 -8 9 -10

Результат выполнения первого задания:

Максимальные элементы по строкам: 17; 2000000000; 9

Столбцы с максимальными элементами: 3; 7; 7

Результат выполнения второго задания:

S1 = -18 S2 = -4

S1 < S2, матрица была изменена:

1 -4 17 -16 15 -14 13 -12

-2 19 20 2000 200000 20000000 2000000000 11

3 -18 5 -6 7 -8 9 -10

Результат выполнения третьего задания:

Число столбцов чётно - был произведён сдвиг «вверх»

-2 19 20 2000 200000 20000000 2000000000 11

3 -18 5 -6 7 -8 9 -10

1 -4 17 -16 15 -14 13 -12

Результат выполнения четвёртого задания:

Матрица, «развёрнутая» против часовой стрелки: 1; -2; 3; -4; 5; -6; 7; -8; 9; -10; 11; -12; 13; -14; 15; -16; 17; -18; 19; 20; 2000; 200000; 20000000; 2000000000;

Результат выполнения пятого задания:

Строки отсортированы в невозрастающем порядке сумм:

-2 19 20 2000 200000 20000000 2000000000 11

3 -4 5 -6 7 -8 9 -10

1 -18 17 -16 15 -14 13 -12

Тест 3: прямоугольная матрица 10x5, наполненная случайными числами.

Исходная матрица:

4490 6540 -12901 20330 -6046

-27459 -22256 26705 14852 -30502

23701 -11502 -30162 -14325 -20739

-15721 -14704 17504 -23934 21020

-27932 7054 -30557 -28698 -19302

-16794 -24715 28069 -2485 -11281

30727 18102 20673 -32373 23140

-16762 -1303 5821 21065 -25295

-24472 27091 -6385 -13002 -22009

-12309 26284 20788 -21316 -25044

Результат выполнения первого задания:

Максимальные элементы по строкам: 20330; 26705; 23701; 21020; 7054

Столбцы с максимальными элементами: 4; 3; 1; 5; 2

Результат выполнения второго задания:

S1 = 4934

S2 = -21774

S1 > S2, матрица не была изменена

Результат выполнения третьего задания:

Число столбцов нечётно - был произведён сдвиг «вниз»

-12309 26284 20788 -21316 -25044

4490 6540 -12901 20330 -6046

-27459 -22256 26705 14852 -30502

23701 -11502 -30162 -14325 -20739

-15721 -14704 17504 -23934 21020

-27932 7054 -30557 -28698 -19302

-16794 -24715 28069 -2485 -11281

30727 18102 20673 -32373 23140

-16762 -1303 5821 21065 -25295

-24472 27091 -6385 -13002 -22009

Результат выполнения четвёртого задания:

Матрица, «развёрнутая» против часовой стрелки: 4490; -27459; 23701; -15721; -27932; -16794; 30727; -16762; -24472; -12309; 26284; 20788; -21316; -25044; -22009; -25295; 23140; -11281; -19302; 21020; -20739; -30502; -6046; 20330; -12901; 6540; -22256; -11502; -14704; 7054; -24715; 18102; -1303; 27091; -6385; -13002; 21065; -32373; -2485; -28698; -23934; -14325; 14852; 26705; -30162; 17504; -30557; 28069; 20673; 5821

Результат выполнения пятого задания:

Строки отсортированы в невозрастающем порядке сумм:

30727 18102 20673 -32373 23140

4490 6540 -12901 20330 -6046

-12309 26284 20788 -21316 -25044

-15721 -14704 17504 -23934 21020

-16762 -1303 5821 21065 -25295

-16794 -24715 28069 -2485 -11281

-27459 -22256 26705 14852 -30502

-24472 27091 -6385 -13002 -22009

23701 -11502 -30162 -14325 -20739

-27932 7054 -30557 -28698 -19302

Тест 4: матрица с большими по модулю числами.

Исходная матрица:

0 -2000000000 -2100000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -1900000000 -200000000 1

Результат выполнения первого задания:

Максимальные элементы по строкам: 1; 1000000000; 1; 1000000000; 1; 1000000000; 1

Столбцы с максимальными элементами: 5; 1; 5; 1; 5; 1; 5

Результат выполнения второго задания:

S1 = -7699999981

S2 = -7499999981

S1 < S2, матрица была изменена:

0 -2000000000 -1900000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2100000000 -2000000000 1

Результат выполнения третьего задания:

Число столбцов нечётно - был произведён сдвиг «вниз»

0 -2000000000 -1900000000 -2000000000 1

0 -2000000000 -2100000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

0 -2000000000 -2000000000 -2000000000 1

1000000000 -800000000 400000000 3 15

Результат выполнения четвёртого задания:

Матрица, «развёрнутая» против часовой стрелки: 0; 1000000000; 0; 1000000000; 0; 1000000000; 0; -2000000000; -1900000000; -2000000000; 1; 15; 1; 15; 1; 15; 1; -2000000000; -2100000000; -2000000000; -800000000; -2000000000; -800000000; -2000000000; -800000000; 400000000; 3; -2000000000; 3; -2000000000; 3; 400000000; -2000000000; 400000000; -2000000000

Результат выполнения пятого задания:

Строки отсортированы в невозрастающем порядке сумм:

1000000000 -800000000 400000000 3 15

1000000000 -800000000 400000000 3 15

1000000000 -800000000 400000000 3 15

0 -2000000000 -1900000000 -2000000000 1

0 -2000000000 -2000000000 -2000000000 1

0 -2000000000 -2000000000 -2000000000 1

0 -2000000000 -2100000000 -2000000000 1

Тест 5: матрица с ошибками.

Исходная матрица:

9999999999 123 fdf

456 rt 8888888888

1234567890 9876543210 789

q 0xf e

-77777777777 000 -13

915 -376 19

ddd -ddd 1111111111

Внутри программы такая матрица будет интерпретирована следующим образом:

0 123 0

456 0 0

1234567890 0 789

0 15 0

0 0 -13

915 -376 19

0 0 1111111111

Результат выполнения первого задания:

Максимальные элементы по строкам: 123; 456; 1234567890; 15; 0; 915; 1111111111

Столбцы с максимальными элементами: 2; 1; 1; 2; 1; 1; 3

Результат выполнения второго задания:

S1 = 123

S2 = 1111111130

S1 < S2, матрица была изменена:

0 0 1111111111

456 0 19

1234567890 0 789

0 15 0

0 0 -13

915 -376 0

0 123 0

Результат выполнения третьего задания:

Число столбцов нечётно - был произведён сдвиг «вниз»

0 0 1111111111

0 123 0

456 0 0

1234567890 0 789

0 15 0

0 0 -13

915 -376 19

Результат выполнения четвёртого задания:

Матрица, «развёрнутая» против часовой стрелки: 0; 456; 1234567890; 0; 0; 915; 0; 0; 1111111111; 19; -13; 0; 789; 0; 0; 123; 0; 0; 15; 0; -376

Результат выполнения пятого задания:

Строки отсортированы в невозрастающем порядке сумм:

1234567890 0 789

0 0 1111111111

915 -376 19

456 0 0

0 123 0

0 15 0

0 0 -13

Приложение 2. Полный листинг формы (файл form.pas)

14 {

15 Модуль, содержащий форму, переменную для хранения исходной матрицы,

16 процедуры синхронизации содержания матрицы и элементов формы, а так же

17 процедуру задания размеров матрицы

18 }

19 unit form;

20

21 interface

22

23 uses

24 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

25 Dialogs, Menus, StdCtrls, ExtCtrls, ComCtrls, Grids,

26 //модули программы

27 fileIO, MatrixOperations;

28

29 type

30 TMainForm = class(TForm)

31 Pages: TPageControl;

32 Task1: TTabSheet;

33 Task2: TTabSheet;

34 Task3: TTabSheet;

35 Task4: TTabSheet;

36 Task5: TTabSheet;

37 Menu: TMainMenu;

38 A1: TMenuItem;

39 load: TMenuItem;

40 save: TMenuItem;

41 N1: TMenuItem;

42 quit: TMenuItem;

43 N4: TMenuItem;

44 M_Task1: TMenuItem;

45 M_Task2: TMenuItem;

46 M_Task3: TMenuItem;

47 M_Task4: TMenuItem;

48 M_Task5: TMenuItem;

49 GroupBox1: TGroupBox;

50 G_Matrix: TStringGrid;

51 E_RowsN: TEdit;

52 Label1: TLabel;

53 Label2: TLabel;

54 E_ColsN: TEdit;

55 B_SetDimms: TButton;

56 SaveDialog: TSaveDialog;

57 OpenDialog: TOpenDialog;

58 Label3: TLabel;

59 Label4: TLabel;

60 G_Task1B: TStringGrid;

61 Label5: TLabel;

62 Label6: TLabel;

63 G_Task1C: TStringGrid;

64 B_Task1Run: TButton;

65 Label7: TLabel;

66 Label8: TLabel;

67 Label9: TLabel;

68 E_Task2S1: TEdit;

69 B_Task2Run: TButton;

70 E_Task2S2: TEdit;

71 L_Task2MatrxChanged: TLabel;

72 Label10: TLabel;

73 B_Task3Run: TButton;

74 L_Task3Result: TLabel;

75 Label11: TLabel;

76 B_Task4Run: TButton;

77 Label12: TLabel;

78 B_Task5Run: TButton;

79 about: TMenuItem;

80 MEM_Task4: TMemo;

81 procedure saveClick(Sender: TObject);

82 procedure loadClick(Sender: TObject);

83 procedure B_SetDimmsClick(Sender: TObject);

84 procedure FormCreate(Sender: TObject);

85 procedure quitClick(Sender: TObject);

86 procedure M_Task1Click(Sender: TObject);

87 procedure M_Task2Click(Sender: TObject);

88 procedure M_Task3Click(Sender: TObject);

89 procedure M_Task4Click(Sender: TObject);

90 procedure M_Task5Click(Sender: TObject);

91 procedure B_Task1RunClick(Sender: TObject);

92 procedure FormDestroy(Sender: TObject);

93 procedure B_Task2RunClick(Sender: TObject);

94 procedure B_Task3RunClick(Sender: TObject);

95 procedure B_Task4RunClick(Sender: TObject);

96 procedure B_Task5RunClick(Sender: TObject);

97 procedure aboutClick(Sender: TObject);

98 private

99 procedure readMatrix;

100 procedure writeMatrix;

101 public

102 published

103 { Public declarations }

104 end;

105

106 var

107 MainForm: TMainForm;

108 workMatrix: TMatrix;

109

110 implementation

111

112 uses Math;

113

114 {$R *.dfm}

115

116 {заполнить матрицу в соответствии с содержанием таблицы на форме}

117 procedure TMainForm.ReadMatrix;

118 var rowN, colN: integer;

119 begin

120 SetLength(workMatrix, G_Matrix.RowCount-1, G_Matrix.ColCount-1);

121 for rowN:= 0 to G_Matrix.RowCount-2 do

122 for colN:= 0 to G_Matrix.ColCount-2 do

123 workMatrix[rowN, colN]:= StrToIntDef(G_Matrix.Cells[colN+1, rowN+1], 0);

124 end;

125

126 {заполнить таблицу на форме в соответствии с содержанием матрицы}

127 procedure TMainForm.writeMatrix;

128 var rowN, colN: integer;

129 begin

130 G_Matrix.Cells[1, 1]:= ;//если матрица пуста

131 //обновим размеры матрицы

132 E_RowsN.Text:= IntToStr(high(workMatrix) + 1);

133 if(E_RowsN.Text <> 0) then

134 E_ColsN.Text:= IntToStr(high(workMatrix[low(workMatrix)]) + 1)

135 else E_ColsN.Text:= 0;

136 B_SetDimmsClick(self);

137 //заполним таблицу

138 for rowN:= low(workMatrix) to high(workMatrix) do

139 for colN:= low(workMatrix[rowN]) to high(workMatrix[rowN]) do

140 G_Matrix.Cells[colN+1, rowN+1]:= IntToStr(workMatrix[rowN, colN]);

141 end;

142

143 {обработчик Файл->Сохранить}

144 procedure TMainForm.saveClick(Sender: TObject);

145 var

146 outFile: TextFile;

147 begin

148 //отобразим диалог выбора файла для сохранения, если отмена - выходим

149 if SaveDialog.Execute = false then exit;

150 AssignFile(outFile, SaveDialog.Files[0]);

151 ReWrite(outFile);//создадим файл

152

153 readMatrix;//прочтём матрицу из таблицы

154 Write2DArray(workMatrix, outFile);//запишем матрицу в файл

155

156 CloseFile(outFile);//закроем файл

157

158 end;

159

160 {обработчик Файл->Загрузить}

161 procedure TMainForm.loadClick(Sender: TObject);

162 var

163 inFile: TextFile;

164 begin

165 //отобразим диалог выбора фала для загрузки, если отмена - выходим

166 if OpenDialog.Execute = false then exit;

167 AssignFile(inFile, OpenDialog.Files[0]);

168 Reset(inFile);//подготовим файл к чтению

169

170 Read2DArray(workMatrix, inFile);//прочтём матрицу из файла

171 writeMatrix;//отобразим матрицу

172

173 CloseFile(inFile);//закроем файл

174 end;

175

176 {обраюотчик уствновки размеров матрицы}

177 procedure TMainForm.B_SetDimmsClick(Sender: TObject);

178 var

179 i: integer;

180 RowsN, ColsN: integer;

181 begin

182 //значения размеров не должны быть меньше 1

183 RowsN:= StrToIntDef(E_RowsN.Text, 0);

184 if RowsN < 1 then begin RowsN:= 1; E_RowsN.Text:= 1 end;

185 ColsN:= StrToIntDef(E_ColsN.Text, 0);

186 if ColsN < 1 then begin ColsN:= 1; E_ColsN.Text:= 1 end;

187 //число строк и столбцов в таблице, учитывая колонку и строку с номерами

188 G_Matrix.RowCount:= RowsN + 1;

189 G_Matrix.ColCount:= ColsN + 1;

190 //в этих таблицах отображаются одномерные массивы из первого задания

191 G_Task1B.RowCount:= RowsN;

192 G_Task1C.RowCount:= RowsN;

193 //одномерный массив из четвёртого задания имеет длину, равную числу элементов исходной матрицы

194 //G_Task4.ColCount:= RowsN * ColsN;

195 //расставим номера строк и столбцов

196 for i:= 0 to RowsN do

197 begin