Удаление нулевых строк/ столбцов из матрицы - C (СИ)
Формулировка задачи:
Добрый день! помогите написать код, желательно на С
Тема: многомерные массивы
Выделить память под многомерный массив, заполнить его произвольным образом, передать обрабатывающей функции и получить её результат ( входная матрица остаётся неизменной, на выходе должно быть новое число или массив)
Задание:
Удалить из матрицы все нулевые строки и столбцы ( в этом и заключается вся проблема)
Решение задачи: «Удаление нулевых строк/ столбцов из матрицы»
textual
Листинг программы
#include <stdio.h>
#include <malloc.h>
int** matrix_input(FILE* _in, int* N, int* M);
void matrix_remzero(int** mat, int* N, int* M);
void matrix_free(int** mat, int N);
int main(void){
int i, j, N, M, **mat;
/* ввод из файла
FILE* fp = fopen("file.txt", "rt");
mat = matrix_input(fp, &N, &M);
fclose(fp);
*/
//ввод с консоли
mat = matrix_input(stdin, &N, &M);
if(mat == NULL){
puts("error");
return 1;
}
//удалить 0
matrix_remzero(mat, &N, &M);
for(i = 0; i < N; ++i){
for(j = 0; j < M; ++j)
printf("%d ", mat[i][j]);
putchar('\n');
}
matrix_free(mat, N);
getchar();
return 0;
}
//удаление нулевых строк/столбцов
void matrix_remzero(int** mat, int* N, int* M){
int i, j, k, n = *N, m = *M;
//удаляем нулевые столбцы
for(j = 0; j < m; ++j){
i = 0;
while((i < n) && (mat[i][j] == 0))
++i;
if(i == n)
break;
}
for(i = j; j < *M; ){
k = 0;
while((k < n) && (mat[k][j] == 0))
++k;
if(k < n)
++i;
else
--m;
if(++j >= *M)
break;
for(k = 0; k < n; ++k)
mat[k][i] = mat[k][j];
}
*M = m;
//удаляем нулевые строки
for(i = 0; i < n; ++i){
j = 0;
while((j < m) && (mat[i][j] == 0))
++j;
if(j == m)
break;
}
for(j = i; j < *N; ){
k = 0;
while((k < m) && (mat[j][k] == 0))
++k;
if(k < m)
++i;
else
--n;
if(++j >= *N)
break;
for(k = 0; k < m; ++k)
mat[i][k] = mat[j][k];
}
//удалить лишние строки
for(i = n; i < *N; ++i)
free(mat[i]);
*N = n;
}
/* ввод матрицы из консоли/файла, пример:
3 5
1 2 0 4 0
0 0 0 0 0
6 7 0 4 0 */
int** matrix_input(FILE* _in, int* N, int* M){
int** mat, n, m, i, j;
if((_in == NULL) || (fscanf(_in, "%d %d", &n, &m) != 2) || (n <= 0) || (m <= 0))
return NULL;
mat = (int**)malloc(sizeof(int*) * n);
if(mat == NULL)
return NULL;
for(i = 0; i < n; ++i){
mat[i] = (int*)malloc(sizeof(int) * m);
if(mat[i] == NULL){
n = i;
goto err;
}
for(j = 0; j < m; ++j){
if((fscanf(_in, "%d", &mat[i][j]) != 1) || (ferror(_in) != 0)){
n = i;
goto err;
}
}
}
*N = n;
*M = m;
return mat;
err:
matrix_free(mat, n);
return NULL;
}
//освобождение памяти из под матрицы
void matrix_free(int** mat, int N){
int i;
for(i = 0; i < N; ++i){
if(mat[i] != NULL){
free(mat[i]);
mat[i] = NULL;
}
}
if(mat != NULL)
free(mat);
}
Объяснение кода листинга программы
В данном коде реализована функция matrix_remzero, которая удаляет нулевые строки и столбцы из матрицы, представленная в виде двумерного массива mat размером N на M.
- Сначала определяется размер матрицы
NиM. - Затем в цикле перебираются все элементы матрицы. Если элемент равен нулю, то его позиция помечается как свободная.
- После этого происходит удаление нулевых строк и столбцов.
- Если в процессе удаления обнаруживается, что матрица стала пустой, то возвращается значение ошибки.
- В конце функция возвращает указатель на матрицу.
Функция
matrix_inputиспользуется для ввода матрицы из файла или с консоли. В случае ввода с консоли или ошибки ввода, матрица считается пустой и возвращается значение ошибки. Функцияmatrix_freeосвобождает память, выделенную под матрицу. В основной функции происходит следующее: - Ввод матрицы с помощью функции
matrix_input. - Вызов функции
matrix_remzeroдля удаления нулевых строк и столбцов. - Вывод матрицы на экран с помощью цикла
for. - Освобождение памяти с помощью функции
matrix_free. - Ввод символа с помощью
getchar()для обработки остального ввода. - Возврат значения 0, указывающего на успешное выполнение программы.