Получить все нулевые элементы выше главной диагонали матрицы - 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 освобождает память, выделенную для матрицы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.167 из 5
Похожие ответы