Получить все нулевые элементы выше главной диагонали матрицы - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Дана матрица целых чисел. Собрать все нулевые элементы выше главной диагонали (заполнение осуществлять параллельно главной диагонали).

Решение задачи: «Получить все нулевые элементы выше главной диагонали матрицы»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. void PrintArr(const int* const a, const size_t N)
  6. {
  7.   size_t i = 0;
  8.  
  9.   printf("===== Array: =====\n");
  10.   for (i = 0; i < N; i++)
  11.   {
  12.     printf("%d ", a[i]);
  13.   }
  14.   printf("\n");
  15.   printf("==================\n");
  16. }
  17.  
  18. size_t GetElementCountAboveMainDiag(const size_t m, const size_t n)
  19. {
  20.   size_t count = 0;
  21.  
  22.   if (m < n)
  23.   {
  24.     count = ((2 * n - m - 1) * m) / 2;
  25.   }
  26.   else
  27.   {
  28.     count = ((1 + m - 1) * m) / 2;
  29.   }
  30.  
  31.   return count;
  32. }
  33.  
  34. void ParallelScan(const int** const a, const size_t M, const size_t N, int* const top)
  35. {
  36.   size_t diagonalIndex = 0;
  37.   size_t i = 0;
  38.   size_t j = 0;
  39.   size_t k = 0;
  40.   size_t offset = 0;
  41.   size_t minSize = 0;
  42.  
  43.   if (M > N)
  44.   {
  45.     minSize = N;
  46.   }
  47.   else
  48.   {
  49.     minSize = M;
  50.   }
  51.  
  52.   /* scanning parallel to main diagonal */
  53.   k = 0;
  54.   for (diagonalIndex = 1; diagonalIndex < N; diagonalIndex++)
  55.   {
  56.     if (N - diagonalIndex < minSize)
  57.     {
  58.       offset++;
  59.     }
  60.  
  61.     for (i = 0; i < minSize - offset; i++)
  62.     {
  63.       j = diagonalIndex + i;
  64.  
  65.       top[k] = a[i][j];
  66.       k++;
  67.     }
  68.   }
  69. }
  70.  
  71. void ParallelWrite(int** const a, const size_t M, const size_t N, const int* const top)
  72. {
  73.   size_t diagonalIndex = 0;
  74.   size_t i = 0;
  75.   size_t j = 0;
  76.   size_t k = 0;
  77.   size_t offset = 0;
  78.   size_t minSize = 0;
  79.  
  80.   if (M > N)
  81.   {
  82.     minSize = N;
  83.   }
  84.   else
  85.   {
  86.     minSize = M;
  87.   }
  88.  
  89.   /* scanning parallel to main diagonal */
  90.   k = 0;
  91.   for (diagonalIndex = 1; diagonalIndex < N; diagonalIndex++)
  92.   {
  93.     if (N - diagonalIndex < minSize)
  94.     {
  95.       offset++;
  96.     }
  97.  
  98.     for (i = 0; i < minSize - offset; i++)
  99.     {
  100.       j = diagonalIndex + i;
  101.  
  102.       a[i][j] = top[k];
  103.       k++;
  104.     }
  105.   }
  106. }
  107.  
  108. int FindFirstNonZero(const int* const a, const size_t N, size_t* const nonZeroIndexPtr)
  109. {
  110.   size_t i = 0;
  111.  
  112.   while (i < N)
  113.   {
  114.     if (a[i] != 0)
  115.     {
  116.       (*nonZeroIndexPtr) = i;
  117.  
  118.       return 1;
  119.     }
  120.     i++;
  121.   }
  122.  
  123.   return 0;
  124. }
  125.  
  126. int SettleTop(int** const a, const size_t M, const size_t N)
  127. {
  128.   int errorCode = 0;
  129.  
  130.   int* topArray = NULL;
  131.  
  132.   size_t i = 0;
  133.   size_t k = 0;
  134.   size_t topArrayLength = 0;
  135.  
  136.   topArrayLength = GetElementCountAboveMainDiag(M, N);
  137.  
  138.   topArray = malloc(topArrayLength * sizeof(*topArray));
  139.  
  140.   if (topArray == NULL)
  141.   {
  142.     errorCode = 1;
  143.   }
  144.   else
  145.   {
  146.     ParallelScan(a, M, N, topArray);
  147.  
  148.     /*
  149.       now we settle zeroes in array, moving all to left side
  150.     */
  151.  
  152.     /* step 1: skip all that may be already on left side (search for starting fill position) */
  153.     if (FindFirstNonZero(topArray, topArrayLength, &k))
  154.     {
  155.       /* step 2: moving all zeroes to left */
  156.       for (i = k; i < topArrayLength; i++)
  157.       {
  158.         if (topArray[i] == 0)
  159.         {
  160.           topArray[i] = topArray[k];
  161.           topArray[k] = 0;
  162.           k++;
  163.         }
  164.       }
  165.  
  166.       /* now elements are settled, exporting top */
  167.       ParallelWrite(a, M, N, topArray);
  168.     }
  169.   }
  170.  
  171.   free(topArray);
  172.  
  173.   return errorCode;
  174. }
  175.  
  176. int ClearBottom(int** const a, const size_t M, const size_t N)
  177. {
  178.   int errorCode = 0;
  179.  
  180.   int* topArray = NULL;
  181.  
  182.   size_t i = 0;
  183.   size_t j = 0;
  184.   size_t k = 0;
  185.   size_t topArrayLength = 0;
  186.  
  187.   topArrayLength = GetElementCountAboveMainDiag(M, N);
  188.  
  189.   topArray = malloc(topArrayLength * sizeof(*topArray));
  190.  
  191.   if (topArray == NULL)
  192.   {
  193.     errorCode = 1;
  194.   }
  195.   else
  196.   {
  197.     /* parallel copy of elements */
  198.     ParallelScan(a, M, N, topArray);
  199.  
  200.     /* skip all that may be already on left side (search for starting fill position) */
  201.     if (FindFirstNonZero(topArray, topArrayLength, &k))
  202.     {
  203.       /* scanning below diagonal (inclusive) and move zeros */
  204.       for (i = 0; i < M; i++)
  205.       {
  206.         for (j = 0; j < i + 1; j++)
  207.         {
  208.           if (a[i][j] == 0)
  209.           {
  210.             a[i][j] = topArray[k];
  211.             topArray[k] = 0;
  212.             k++;
  213.           }
  214.         }
  215.       }
  216.  
  217.       /* exporting top */
  218.       ParallelWrite(a, M, N, topArray);
  219.     }
  220.   }
  221.  
  222.   free(topArray);
  223.  
  224.   return errorCode;
  225. }
  226.  
  227. void CreateAndGenerateMatrix(int*** const matrixPtr, size_t* const rowCountPtr, size_t* const colCountPtr)
  228. {
  229.   int** a = NULL;
  230.  
  231.   size_t m = 0;
  232.   size_t n = 0;
  233.   size_t i = 0;
  234.   size_t j = 0;
  235.  
  236.   m = rand() % 11 + 1;
  237.   n = rand() % 11 + 1;
  238.  
  239.   a = malloc(m * sizeof(*a));
  240.   for (i = 0; i < m; i++)
  241.   {
  242.     a[i] = malloc(n * sizeof(**a));
  243.   }
  244.  
  245.   for (i = 0; i < m; i++)
  246.   {
  247.     for (j = 0; j < n; j++)
  248.     {
  249.       a[i][j] = rand() % 10;
  250.     }
  251.   }
  252.  
  253.   (*matrixPtr) = a;
  254.   (*rowCountPtr) = m;
  255.   (*colCountPtr) = n;
  256. }
  257.  
  258. void PrintMatrix(const int** const a, const size_t M, const size_t N)
  259. {
  260.   size_t i = 0;
  261.   size_t j = 0;
  262.  
  263.   printf("===============\n");
  264.   for (i = 0; i < M; i++)
  265.   {
  266.     for (j = 0; j < N; j++)
  267.     {
  268.       printf("%d ", a[i][j]);
  269.     }
  270.     printf("\n");
  271.   }
  272.   printf("===============\n");
  273. }
  274.  
  275. void FreeMatrix(int*** const matrixPtr, size_t* const rowCountPtr, size_t* const colCountPtr)
  276. {
  277.   size_t i = 0;
  278.  
  279.   for (i = 0; i < (*rowCountPtr); i++)
  280.   {
  281.     free((*matrixPtr)[i]);
  282.     (*matrixPtr)[i] = NULL;
  283.   }
  284.  
  285.   free(*matrixPtr);
  286.  
  287.   (*matrixPtr) = NULL;
  288.   (*rowCountPtr) = 0;
  289.   (*colCountPtr) = 0;
  290. }
  291.  
  292. int main(void)
  293. {
  294.   int** a = NULL;
  295.  
  296.   size_t m = 0;
  297.   size_t n = 0;
  298.  
  299.   srand(time(NULL));
  300.  
  301.   CreateAndGenerateMatrix(&a, &m, &n);
  302.  
  303.   PrintMatrix(a, m, n);
  304.  
  305.  
  306.   SettleTop(a, m, n);
  307.  
  308.   ClearBottom(a, m, n);
  309.  
  310.  
  311.   PrintMatrix(a, m, n);
  312.  
  313.   FreeMatrix(&a, &m, &n);
  314.  
  315.   return 0;
  316. }

Объяснение кода листинга программы

Код представляет собой функцию main, которая генерирует случайную матрицу размером m x n и выводит ее на экран. Затем он использует две функции ParallelScan и ParallelWrite, чтобы заполнить верхнюю диагональ матрицы нулями, сначала слева направо, а затем сверху вниз. Функция FindFirstNonZero используется для поиска первого ненулевого элемента в верхнем массиве, а функция ClearBottom для очистки нижней части матрицы, перемещая все нули влево. Наконец, матрица выводится на экран еще раз, и функция FreeMatrix освобождает память, выделенную для матрицы.

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


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

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

6   голосов , оценка 4.167 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы