Как выполнить сглаживание матрицы через указатели? Язык Си
Нужно выполнить сглаживание матрицы через указатели. Подскажите каким способом это реализовать, так как мои попытки приводят к выводу неверных значений или выходу за границы массива.
P.S. Массив должен быть динамическим, в данном коде число 10 взято для проверки.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <locale.h>
double sum(double** pmatrix, int rows, int columns);
void subtraction (double **pmatrix, int rows, int columns);
int main(void) {
setlocale(LC_ALL, "RU");
int rows = 10, columns = 10;
int i, j;
double matrix[rows][columns];
double **pmatrix;
srand(time(NULL));
pmatrix = (double**)malloc(rows * sizeof(double*));
for (i = 0; i<rows; i++){
pmatrix[i] = (double*)malloc(columns * sizeof(double));
}
//ЗАПОЛНЕНИЕ МАССИВА
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
*(*(pmatrix+i)+j) = rand() % 10;
}
}
//ВЫВОД МАССИВА ДЛЯ ПРОСМОТРА
for (i = 0; i < rows; i++) {
printf("\n\n");
for (j = 0; j < columns; j++) {
printf("%lf\t", *(*(pmatrix+i)+j));
}
}
//СГЛАЖИВАНИЕ МАТРИЦЫ (don't work!)
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
if ((i > 0) && (j > 0) && (i < rows-1) && (j < columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i + 1))+j) + *(*(pmatrix + i)+(j +1)) + *(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j -1 ))) / 4; // внутренний квадрат
}
else if ((i == 0) && (j > 0) && (j < columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j -1 )) + *(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 3; // верхний внутренний ряд
}
else if ((i == 0) && (j == 0)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 2;
} // левый верхний угол
else if ((i == 0) && (j == columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j - 1))) / 2;
} // правый верхний угол
else if ((j == 0) && (i > 0) && (i < rows-1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j + 1)) + *(*(pmatrix + i)+(j + 1))) / 3;
} // левый внутренний ряд
else if ((i == rows - 1) && (j == 0)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j + 1))) / 2;
} // левый нижний угол
else if ((i == rows - 1) && (j == columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1))) / 2;
} // правый нижний угол
else if ((i == rows - 1) && (j > 0) && (j < columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1)) + *(*(pmatrix + i)+(j + 1))) / 3;
} // нижний внутренний ряд
else if ((i < rows - 1) && (i > 0) && (j == columns - 1)) {
*(*(pmatrix + i)+j) = (*(*(pmatrix + (i - 1))+j) + *(*(pmatrix + i)+(j - 1)) + *(*(pmatrix + (i+ 1))+j)) / 3;
} // правый внутренний ряд
}
}
printf("\n\t ВЫВОД СГЛАЖЕННОЙ МАТРИЦЫ\n");
for (i = 0; i < rows; i++) {
printf("\n\n");
for (j = 0; j < columns; j++) {
printf("%lf\t", *(*(pmatrix + i ) + j));
}
}
//ВЫЧИСЛЕНИЕ СУММЫ МОДУЛЕЙ ЭЛЕМЕНТОВ МАТРИЦЫ НИЖЕ ГЛАВНОЙ ДИАГОНАЛИ
sum(pmatrix, rows,columns);
//ПОЭЛЕМЕНТНОЕ ВЫЧИТАНИЕ ПОСЛЕДНЕЙ СТРОКИ ИЗ ВСЕХ СТРОК КРОМЕ ПОСЛЕДНЕЙ
subtraction(pmatrix, rows, columns);
printf("\n\t ВЫВОД МАТРИЦЫ ПОСЛЕ ВЫЧИТАНИЯ ПОСЛЕДНЕЙ СТРОКИ\n");
for (i = 0; i < rows; i++) {
printf("\n\n");
for (j = 0; j < columns; j++) {
printf("%lf\t", *(*(pmatrix + i ) + j));
}
}
//ОСВОБОЖДЕНИЕ ПАМЯТИ
for (i = 0; i < rows; i++)
{
free(*(pmatrix+i));
}
free(pmatrix);
return 0;
}
//ВЫЧИСЛЕНИЕ СУММЫ МОДУЛЕЙ ЭЛЕМЕНТОВ МАТРИЦЫ НИЖЕ ГЛАВНОЙ ДИАГОНАЛИ
double sum (double **pmatrix, int rows, int columns ){
double s = 0;
for (int i = 1; i < rows; i++) {
for (int j = 0; j < i ; j++) {
s += fabs(*(*(pmatrix + i)+j));
}
}
printf("\n\n сумма модулей элементов матрицы ниже главной диагонали = %lf\n", s);
return (s);
}
//ПОЭЛЕМЕНТНОЕ ВЫЧИТАНИЕ ПОСЛЕДНЕЙ СТРОКИ ИЗ ВСЕХ СТРОК КРОМЕ ПОСЛЕДНЕЙ
void subtraction (double **pmatrix, int rows, int columns){
for (int i = 0; i < rows - 1; i++) {
for (int j = 0; j < columns; j++) {
*(*(pmatrix + i) + j) = *(*(pmatrix + i) + j) - *(*(pmatrix + rows - 1) + j);
}
}
}```
Ответы (1 шт):
Выполнение сглаживания по указанному правилу без вспомогательной матрицы очень и очень трудоемкая задача, и все равно без вспомогательных массивов не обойтись, так как нужно хранить предыдущие значения элементов.
Вы совершенно зря выделяете такое количество классов элементов матрицы. Давайте заведем временную переменные, в одну будем сохранять сумму доступных элементов, а в другую их количество. А потом посчитаем среднее арифметическое.
Предлагаю функцию сглаживания
double** matrix_smooth(double** pmatrix, int rows, int columns) { double **res; double tmp; int count; res = (double**)malloc(rows * sizeof(double*)); for (int i = 0; i < rows; i++) { res[i] = (double*)malloc(columns * sizeof(double)); } for (int i = 0; i < rows; i++) for (int j = 0; j < columns; j++) { count = 0; tmp = 0; if (i - 1 >= 0) { tmp = tmp + pmatrix[i-1][j]; count++; } if (i + 1 < rows) { tmp = tmp + pmatrix[i + 1][j]; count++; } if (j - 1 >= 0) { tmp = tmp + pmatrix[i][j-1]; count++; } if (j + 1 < columns) { tmp = tmp + pmatrix[i][j+1]; count++; } tmp = tmp / count; res[i][j] = tmp; } return res; }