Получить все нулевые элементы выше главной диагонали матрицы - C (СИ)
Формулировка задачи:
Дана матрица целых чисел. Собрать все нулевые элементы выше
главной диагонали (заполнение осуществлять параллельно главной диагонали).
Решение задачи: «Получить все нулевые элементы выше главной диагонали матрицы»
textual
Листинг программы
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- void PrintArr(const int* const a, const size_t N)
- {
- size_t i = 0;
- printf("===== Array: =====\n");
- for (i = 0; i < N; i++)
- {
- printf("%d ", a[i]);
- }
- printf("\n");
- printf("==================\n");
- }
- size_t GetElementCountAboveMainDiag(const size_t m, const size_t n)
- {
- size_t count = 0;
- if (m < n)
- {
- count = ((2 * n - m - 1) * m) / 2;
- }
- else
- {
- count = ((1 + m - 1) * m) / 2;
- }
- return count;
- }
- void ParallelScan(const int** const a, const size_t M, const size_t N, int* const top)
- {
- size_t diagonalIndex = 0;
- size_t i = 0;
- size_t j = 0;
- size_t k = 0;
- size_t offset = 0;
- size_t minSize = 0;
- if (M > N)
- {
- minSize = N;
- }
- else
- {
- minSize = M;
- }
- /* scanning parallel to main diagonal */
- k = 0;
- for (diagonalIndex = 1; diagonalIndex < N; diagonalIndex++)
- {
- if (N - diagonalIndex < minSize)
- {
- offset++;
- }
- for (i = 0; i < minSize - offset; i++)
- {
- j = diagonalIndex + i;
- top[k] = a[i][j];
- k++;
- }
- }
- }
- void ParallelWrite(int** const a, const size_t M, const size_t N, const int* const top)
- {
- size_t diagonalIndex = 0;
- size_t i = 0;
- size_t j = 0;
- size_t k = 0;
- size_t offset = 0;
- size_t minSize = 0;
- if (M > N)
- {
- minSize = N;
- }
- else
- {
- minSize = M;
- }
- /* scanning parallel to main diagonal */
- k = 0;
- for (diagonalIndex = 1; diagonalIndex < N; diagonalIndex++)
- {
- if (N - diagonalIndex < minSize)
- {
- offset++;
- }
- for (i = 0; i < minSize - offset; i++)
- {
- j = diagonalIndex + i;
- a[i][j] = top[k];
- k++;
- }
- }
- }
- int FindFirstNonZero(const int* const a, const size_t N, size_t* const nonZeroIndexPtr)
- {
- size_t i = 0;
- while (i < N)
- {
- if (a[i] != 0)
- {
- (*nonZeroIndexPtr) = i;
- return 1;
- }
- i++;
- }
- return 0;
- }
- int SettleTop(int** const a, const size_t M, const size_t N)
- {
- int errorCode = 0;
- int* topArray = NULL;
- size_t i = 0;
- size_t k = 0;
- size_t topArrayLength = 0;
- topArrayLength = GetElementCountAboveMainDiag(M, N);
- topArray = malloc(topArrayLength * sizeof(*topArray));
- if (topArray == NULL)
- {
- errorCode = 1;
- }
- else
- {
- ParallelScan(a, M, N, topArray);
- /*
- now we settle zeroes in array, moving all to left side
- */
- /* step 1: skip all that may be already on left side (search for starting fill position) */
- if (FindFirstNonZero(topArray, topArrayLength, &k))
- {
- /* step 2: moving all zeroes to left */
- for (i = k; i < topArrayLength; i++)
- {
- if (topArray[i] == 0)
- {
- topArray[i] = topArray[k];
- topArray[k] = 0;
- k++;
- }
- }
- /* now elements are settled, exporting top */
- ParallelWrite(a, M, N, topArray);
- }
- }
- free(topArray);
- return errorCode;
- }
- int ClearBottom(int** const a, const size_t M, const size_t N)
- {
- int errorCode = 0;
- int* topArray = NULL;
- size_t i = 0;
- size_t j = 0;
- size_t k = 0;
- size_t topArrayLength = 0;
- topArrayLength = GetElementCountAboveMainDiag(M, N);
- topArray = malloc(topArrayLength * sizeof(*topArray));
- if (topArray == NULL)
- {
- errorCode = 1;
- }
- else
- {
- /* parallel copy of elements */
- ParallelScan(a, M, N, topArray);
- /* skip all that may be already on left side (search for starting fill position) */
- if (FindFirstNonZero(topArray, topArrayLength, &k))
- {
- /* scanning below diagonal (inclusive) and move zeros */
- for (i = 0; i < M; i++)
- {
- for (j = 0; j < i + 1; j++)
- {
- if (a[i][j] == 0)
- {
- a[i][j] = topArray[k];
- topArray[k] = 0;
- k++;
- }
- }
- }
- /* exporting top */
- ParallelWrite(a, M, N, topArray);
- }
- }
- free(topArray);
- return errorCode;
- }
- void CreateAndGenerateMatrix(int*** const matrixPtr, size_t* const rowCountPtr, size_t* const colCountPtr)
- {
- int** a = NULL;
- size_t m = 0;
- size_t n = 0;
- size_t i = 0;
- size_t j = 0;
- m = rand() % 11 + 1;
- n = rand() % 11 + 1;
- a = malloc(m * sizeof(*a));
- for (i = 0; i < m; i++)
- {
- a[i] = malloc(n * sizeof(**a));
- }
- for (i = 0; i < m; i++)
- {
- for (j = 0; j < n; j++)
- {
- a[i][j] = rand() % 10;
- }
- }
- (*matrixPtr) = a;
- (*rowCountPtr) = m;
- (*colCountPtr) = n;
- }
- void PrintMatrix(const int** const a, const size_t M, const size_t N)
- {
- size_t i = 0;
- size_t j = 0;
- printf("===============\n");
- for (i = 0; i < M; i++)
- {
- for (j = 0; j < N; j++)
- {
- printf("%d ", a[i][j]);
- }
- printf("\n");
- }
- printf("===============\n");
- }
- void FreeMatrix(int*** const matrixPtr, size_t* const rowCountPtr, size_t* const colCountPtr)
- {
- size_t i = 0;
- for (i = 0; i < (*rowCountPtr); i++)
- {
- free((*matrixPtr)[i]);
- (*matrixPtr)[i] = NULL;
- }
- free(*matrixPtr);
- (*matrixPtr) = NULL;
- (*rowCountPtr) = 0;
- (*colCountPtr) = 0;
- }
- int main(void)
- {
- int** a = NULL;
- size_t m = 0;
- size_t n = 0;
- srand(time(NULL));
- CreateAndGenerateMatrix(&a, &m, &n);
- PrintMatrix(a, m, n);
- SettleTop(a, m, n);
- ClearBottom(a, m, n);
- PrintMatrix(a, m, n);
- FreeMatrix(&a, &m, &n);
- return 0;
- }
Объяснение кода листинга программы
Код представляет собой функцию main
, которая генерирует случайную матрицу размером m x n
и выводит ее на экран. Затем он использует две функции ParallelScan
и ParallelWrite
, чтобы заполнить верхнюю диагональ матрицы нулями, сначала слева направо, а затем сверху вниз. Функция FindFirstNonZero
используется для поиска первого ненулевого элемента в верхнем массиве, а функция ClearBottom
для очистки нижней части матрицы, перемещая все нули влево. Наконец, матрица выводится на экран еще раз, и функция FreeMatrix
освобождает память, выделенную для матрицы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д