Мне нужно найти кластер в 2-м массиве. Это означает, что мне нужно найти наибольшее количество «1» в 2-мерном массиве. В массиве всего «0» и «1». Связанные числа могут быть все "1" в каждом направлении (8 направлений), например, эта матрица имеет кластер из 6
Пример: выход = 6
ma[] = { 1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 1, 0, 0, //because of diagonal
0, 1, 0, 0, 1 }; // the last "1" should not be counted
К сожалению, я понятия не имею, как это сделать. Вот мой последний код, с помощью которого я могу просто подсчитать все «1» в массиве 2d.
void cluster(int *mat, int rows, int cols) {
int i, j;
int target = 0;
printf("\n+++++++++++++++++++++++++++++++\nbiggst cluster\n\n");
for(j = 0; j < cols; j++) {
for (i = 0; i < rows; i++) {
if (mat[j*rows+i] == 1)
target = target + 1;
}
}
printf("%d ", target);
}
Я действительно был бы признателен за небольшой код или алгоритм для решения этой проблемы.
Приветствует
3 ответа
К проблеме можно подойти, сначала определив и сформулировав цели, а затем разбив ее на шаги, необходимые для решения:
Во-первых, некоторые пояснения к постановке вашей проблемы:
Следующий не определяет 2D-матрицу , он создается как одномерный массив с 20 элементами.
ma[] = { 1, 1, 0, 0, 0,
1, 1, 0, 0, 0,
0, 0, 1, 0, 0, //because of diagonal
0, 1, 0, 0, 1 }; // the last "1" should not be counted
наибольшее количество единиц в двумерном массиве
Предположим, вы имеете в виду , количество соседних элементов со значением == 1 в массиве
и
цифры могут состоять из 1 в каждом направлении (8 направлений)
На самом деле есть только два направления в массиве C . (См. Объяснение ниже)
Для ясности измените некоторые определения:
1) определите кластер значений:
кластер - это 1 или несколько элементов массива, содержащих значение 1 и смежных с другим элементом массива в любом направлении. (см. комментарии к рядом ниже)
2) определите 2D-массив в C: 2D-массив в C - это область непрерывной памяти, в которой элементы массива расположены в виде основных строк:
Example: int array[4][5] = {{1,0,0,0,0},{0,1,0,0,0},{0,0,1,0,0},{0,0,0,1,0}};
Концептуально выглядит так:
|1|0|0|0|0|
|0|1|0|0|0|
|0|0|1|0|0|
|0|0|0|1|0| //cluster of four
Но в памяти выглядит так:
|1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|1|0| //cluster of zero (no "1" elements next to another)
| | | | |
[0][0] [1][0] [2][0] [3][0] [3][4]
Обратите внимание, что на самом деле Смежный имеет другую перспективу.
Таким образом, предполагаемое решение имеет мало общего со смежной памятью и больше связано с обозначением массива, например [i][j]
.
Тогда для вашей цели смежный должен быть определен как:
близость индексов элемента, где другой элемент находится не более чем на 1 индекс в любом направлении:
Учитывая int array[ROWS][COLS];
Вот тест на смежность : (используя наше определение)
array[m][n]
примыкает к array[o][p]
, когда:
!((m == o) && (n == p)) //same element
(abs(m - o) <= 1) && (abs(n-p) <= 1)
((m + o) < ROWS) &&((n + p) < COLS)
Проблема может быть решена путем обхода всех элементов, строка за строкой, и каждого элемента, проверки близости к другому элементу путем просмотра каждого окружающего индекса.
Существуют более эффективные с точки зрения памяти методы, но: вы можете построить другую матрицу того же размера и инициализировать ее всеми нулями. Пусть это матрица B.
Начните сканирование первой матрицы A со счетчиком N, установленным на 1, и как только вы обнаружите в A «1» с «0» в B (т. Е. Aij = 1, Bij = 0), поместите его в list и инициализируйте M значением 0.
Затем, пока список не станет пустым:
- выберите элемент из списка и увеличьте M.
- посмотрите на его соседей (вам нужны только (x-1, y), (x + 1, y), (y + 1, x-1), (y + 1, x) и (y + 1, x + 1) )) и если у них Ax'y '= 1 и Bx'y' = 0, установите Bx'y 'в N и добавьте их в список.
Когда список пуст, вы нашли M элементов в кластере N, поэтому установите ClusterSize[N]=M
.
Когда вы закончите, найдите максимальное значение ClusterSize, предположим, что это ClusterSize [K]; то все элементы, где Bij = K, принадлежат кластеру мощности M.
Алгоритм однократно обращается ко всем элементам матрицы. Вам нужно не более W * H / 4 элементов для массива Cluster (у вас не может быть более W * H / 4 кластеров с одним элементом без некоторых элементов, соединяющих и уменьшающих количество кластеров), не более W * H для AncillaryMatrix , и элементы W * H для List. Вы можете динамически распределять и перераспределять их по своему желанию, но, если не требуется для экономии памяти, я бы просто использовал пессимистическое значение.
Псевдокод:
int **AncillaryMatrix;
if (NULL == (AncillaryMatrix = malloc(sizeof(int *)*H))) {
return ERROR_OUTOFMEMORY;
}
for (j = 0; j < H; j++) {
if (NULL == (AncillaryMatrix[j] = malloc(sizeof(int)*W))) {
while (--j) {
free(AncillaryMatrix[j]); AncillaryMatrix[j] = NULL;
}
free(AncillaryMatrix); AncillaryMatrix = NULL;
return ERROR_OUTOFMEMORY;
}
for (i = 0; i < W; i++) {
AncillaryMatrix[j][i] = 0;
}
}
N = 1;
for (j = 0; j < H; j++) {
for (i = 0; i < W; i++) {
if (0 == BaseMatrix[j][i]) {
continue;
}
if (0 != AncillaryMatrix[j][i]) {
continue;
}
if (0 == (Cluster[N] = FillMatrix(BaseMatrix, AncillaryMatrix, W, H, i, j, N)) {
// Handle out of memory error.
}
N++;
}
}
// Free ancillarymatrix, unless you need to know the items in the K-th cluster
j = H; while (j--) {
free(AncillaryMatrix[j]); AncillaryMatrix[j] = NULL;
}
free(AncillaryMatrix); AncillaryMatrix = NULL;
// Find maximum value in Cluster[1..N-1].
// Cluster[0] is not used because "0" in AncillaryMatrix means "no cluster here"
// So the number of clusters is really N-1.
for (j = 1, i = 2; i < N; i++) {
if (Cluster[i] > Cluster[j]) {
j = i;
}
}
// Largest cluster identified by j, has Cluster[j] members.
////
int FillMatrix(int **B, int **A, int W, int H, int i, int j, int N) {
int M = 0;
typedef struct Item { int x, int y } *List;
if (null == (List = malloc(sizeof(Item)*W*H))) {
return 0;
}
List[l].x = i;
List[l].y = j;
A[j][i] = N;
l++;
while (l) {
l--; M++;
int ii = List[l].x;
int jj = List[l].y;
// Add neighbours. NOTE: add code to handle case when jj or ii is 0
// or jj is H-1 or ii is W-1.
// check jj,ii-1 (could use a macro)
if (B[jj][ii-1]) {
if (0 == A[jj][ii-1]) {
List[l].x = ii-1;
List[l].y = jj;
l++;
}
}
CHECK(jj, ii+1)
CHECK(jj+1, ii-1)
CHECK(jj+1, ii)
CHECK(jj+1, ii+1)
}
free(List); // List = NULL;
return M;
}
Ребята, я наконец нашел действительно простое решение этой проблемы, просто посмотрите сюда ...
void cluster(int rows, int cols) {
int ma4[4][5] = {{0, 1, 0, 0, 0}, // 1. Zeile
{1, 1, 0, 0, 0}, // 2. Zeile
{1, 1, 0, 1, 0}, // 3. Zeile
{0, 1, 0, 0, 0}}; // 4. Zeile
int i = 0;
int j = 0;
int target = 0;
printf("\n+++++++++++++++++++++++++++++++\nbiggst cluster\n\n");
for(j = 0; j < cols; j++) {
for (i = 0; i < rows; i++) {
if (ma4[j][i] == 1) {
if (ma4[j-1][i] || ma4[j][i-1] || ma4[j+1][i] || ma4[j][i+1] || ma4[j-1][i-1] || ma4[j+1][i+1] || ma4[j-1][i+1] || ma4[j+1][i-1] == 1)
target += 1;
}
}
}
printf("%d ", target);
}
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.