1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
| #include <iostream>
#include <locale.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <iomanip>
int n = 0, m = 0;
int i = 0, j = 0, k = 0, imax = 0, jmax = 0;
// Копирует элементы матрицы parr, не меньшие k, в обнулённую матрицу parr1
void CopyMatrixNumber(double** parr, double** parr1, int const k)
{
for(i = 0; i < n + 1; ++i)//идем по строкам
for(j = 0; j < m + 1; ++j)//идем по столбцам
{
if(parr[i][j] >= k)//если элемент первого массива больше входной константы
parr1[i][j] = k;//записывем на его место во втором массиве константу
else
parr1[i][j] = 0;//иначе пишем 0
}
}
// Поиск максимума в матрице n x m
int MaxElement(double** pmatrix)
{//странная функция - матрица вещественная - возвращает int
int max = 0;// за max я бы взял pmatrix[0][0] - вдруг все элементы отрицательные
for(i = 0; i < n; ++i)//бежим по матрице
for(j = 0; j < m; ++j)
if(pmatrix[i][j] > max)// сравниваем текущий элемент с максимальным
{
max = pmatrix[i][j];//если он (текущий) больше, в max пишем текущий элемент
imax = i;// запоминаем координаты максимального элемента
jmax = j;
}
return max;//возвращаем максимальный элемент
}
// Вывод матрицы n x m
void DisplayMatrix(double** pmatrix)
{// думаю тут все понятно
for(i = 0; i < n; ++i)
{
for(j = 0; j < m; ++j)
std::cout << std::setw(10) << std::left << pmatrix[i][j];
std::cout << "\n\n";
}
}
// Освобождает память из-под матрицы
template<typename T>
void FreeMemory(T** pmatrix, int const rows)
{
for(int i = 0; i < rows; ++i)
{
delete[] pmatrix[i];
pmatrix[i] = 0;
}
delete[] pmatrix;
pmatrix = 0;
}
// Выделение памяти под матрицу
template<typename T>
T**& GetMemory(T**& pmatrix, int const rows, int const columns)
{
int i = 0;
try
{
pmatrix = new T*[rows];
for(i = 0; i < rows; ++i)
pmatrix[i] = 0;
for(i = 0; i < rows; ++i)
pmatrix[i] = new T[columns];
}
catch(std::bad_alloc const& exc)
{
std::cerr << "GetMemory: Exception: Неуспешное выделение памяти\n\n";
FreeMemory(pmatrix, rows);
throw;
}
return pmatrix;
}
// Заполняет матрицу с клавиатуры
double** FillFromCin(double**& pmatrix, int& rows, int& columns)
{
try
{
if(pmatrix)
throw "FillFromCin: pmatrix != 0";
std::cout << "Число строк: ";
std::cin >> rows;
std::cout << "Число столбцов: ";
std::cin >> columns;
std::cout << '\n';
GetMemory(pmatrix, rows, columns);
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
std::cout << "pmatrix[" << i << "][" << j << "] = ";
std::cin >> pmatrix[i][j];
}
std::cout << '\n';
}
}
catch(char const* const exc)
{
std::cerr << "FillFromCin: Exception: " << exc << "\n\n";
throw;
}
return pmatrix;
}
// Сортировка совместно последней строки и последнего столбца по убыванию
double** SortPrintLastColumnRow(double** pmatrix)
{
double* parr = new double[n + m - 1];
int arrsize = 0;
for(i = 0; i < n; ++i)
for(j = 0; j < m; ++j)
if(j == m - 1 || i == n - 1)
{
parr[arrsize] = pmatrix[i][j];
++arrsize;
}
// Сортировка простыми вставками по убыванию
for(i = 0; i < arrsize; ++i)
{
double tmp = parr[i];
for(j = i - 1; j >= 0 && parr[j] < tmp; --j)
parr[j + 1] = parr[j];
parr[j + 1] = tmp;
}
/*for(i = 0; i < n; ++i)
for(j = 0; j < m; ++j)
if(j == m - 1 || i == n - 1)
{
--arrsize;
pmatrix[i][j] = parr[arrsize];
}
*/
for(i = 0; i < arrsize; ++i)
std::cout << std::setw(8) << std::left << parr[i];
std::cout << "\n\n";
delete[] parr;
return pmatrix;
}
int main()
{
try
{
setlocale(LC_ALL, "rus");
std::string const filepath = "matrix.txt";
double** pmatrix = 0;
FillFromCin(pmatrix, n, m);
// Выделение памяти для двух вспомогательных матриц
double** parr = 0, **parr1 = 0;
GetMemory(parr, n + 1, m + 1);
GetMemory(parr1, n + 1, m + 1);
// Обнуляем вспомогательные матрицы
for(i = 0; i < n + 1; ++i)
for(j = 0; j < m + 1; ++j)
{
parr[i][j] = 0;
parr1[i][j] = 0;
}
//Инициируем матрицу parr
for(i = 0; i < n; ++i)
for(j = 0; j < m; ++j)
if(pmatrix[i][j] >= 0)
parr[i][j] = 1;
std::cout << "Исходная матрица\n";
//DisplayMatrix(parr);
DisplayMatrix(pmatrix);
// Нахождение суммы по столбцам методом Кадане
for(i = n - 1; i >= 0; --i)
for(j = m - 1; j >= 0; --j)
{
if(parr[i][j])
parr[i][j] += parr[i][j + 1];
}
//std::cout << "\n1. Сумма по столбцам\n";
//DisplayMatrix(parr);
// Поиск максимума в матрице
int maxrows = MaxElement(parr);
// Сумма по строкам
int maxcol = 0;
int imaxcol = 0, jmaxcol = 0, kmax = 0;
for(k = 1; k <= maxrows; ++k)
{
CopyMatrixNumber(parr, parr1, k);
//std::cout << "\ncopied: k:" << k << "\n";
//DisplayMatrix(parr1);
// Сумма по строкам
for(j = m - 1; j >= 0; --j)
{
for(i = n - 1; i >= 0; --i)
{
if(parr1[i][j])
parr1[i][j] += parr1[i + 1][j];
}
}
int tmpmax = MaxElement(parr1);
//std::cout << "\n\nk: " << k << ", tmpmax: " << tmpmax << "\n\n";
//DisplayMatrix(parr1);
if(maxcol < tmpmax)
{
maxcol = tmpmax;
imaxcol = imax;
jmaxcol = jmax;
kmax = k;
}
}
//std::cout << "\n\nЧисло элементов в подматрице: " << maxcol << "\n";
std::cout << "Найденная подматрица:\n";
std::cout << "Размер подматрицы: " << maxcol / kmax << " x " << kmax << '\n';
std::cout << "Координаты левого верхнего элемента подматрицы: ";
std::cout << "[ " << imaxcol << " , " << jmaxcol << " ]\n\n";
double** pmatrixres = new double*[maxcol / kmax];
for(i = 0; i < maxcol / kmax; ++i)
pmatrixres[i] = new double[kmax];
for(i = imaxcol; i < imaxcol + maxcol / kmax; ++i)
{
for(j = jmaxcol; j < jmaxcol + kmax; ++j)
{
pmatrixres[i - imaxcol][j - jmaxcol] = pmatrix[i][j];
std::cout << std::setw(10) << std::left << pmatrixres[i - imaxcol][j - jmaxcol];
}
std::cout << "\n\n";
}
std::cout << "\nОтсортированные совместно по убыванию последние столбец и строка\n";
SortPrintLastColumnRow(pmatrix);
// Освобождение памяти
FreeMemory(pmatrix, n);
FreeMemory(parr, n + 1);
FreeMemory(parr1, n + 1);
FreeMemory(pmatrixres, maxcol / kmax);
}
catch(...){}
system("pause");
return 0;
} |