Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке? Тип приложения - не Qt, Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.
|
Статические и динамические матрицы
6.4 Решение некоторых задач линейной алгебры
В этом параграфе рассмотрим использование матриц при решении таких задач линейной алгебры, как сложение, вычитание и умножение матриц, решение систем линейных алгебраических уравнений, вычисление определителя и обратной матрицы.
Задача 6.9.Заданы четыре матрицы вещественных чисел. Вычислить матрицу
.
Суммой (разностью) матриц одинаковой размерности и
называется матрица
, элементы которой получаются сложением
(вычитанием
) соответствующих элементов исходных матриц.
Напомним алгоритм умножения матриц на примере

Воспользовавшись правилом "строка на столбец", получим матрицу:

Произведением матриц и
является матрица
, каждый элемент которой
вычисляется по формуле:



Операция умножения имеет смысл только в том случае, если количество строк левой матрицы совпадает с количеством столбцов правой. Кроме того, .
При решении задачи будем использовать динамические матрицы и двойные указатели. Напишем следующие функции.
-
float **sum_m(float **A, float **B, int N, int M) — функция формирует матрицу, которая является суммой двух матриц. Здесь A, B — указатели на исходные матрицы, N, M — количество строк и столбцов матриц, функция возвращает указатель на сформированную матрицу, которая является суммой двух матриц
и
.
-
float **minus_m(float **A, float **B, int N, int M) — функция формирует матрицу, которая является разностью двух матриц. Здесь A, B — указатели на исходные матрицы, N, M — количество строк и столбцов матриц, функция возвращает указатель на сформированную матрицу, которая является разностью двух матриц
и
.
-
float **product_m(float **A, float **B, int N, int M, int L) — функция формирует матрицу, которая является произведением двух матриц. Здесь A, B — указатели на исходные матрицы. Матрица
имеет
строк и
столбцов, матрица
имеет
строка и
столбцов, функция возвращает указатель на сформированную матрицу, которая является произведением двух матриц
и
.
-
float **create_m(int N, int M) — функция создаёт матрицу, в которой будет
строк и
столбцов, осуществляет ввод элементов матрицы, функция возвращает указатель на сформированную матрицу.
-
void output_m(float **A, int N, int M) — функция построчного вывода на экран матрицы
, которая имеет
строк и
столбцов.
Далее приведён текст программы с комментариями.
#include <iostream> using namespace std; //функция вычисления суммы двух матриц. float **sum_m( float **A, float **B, int N, int M) { int i, j; float **temp; //указатель для хранения результирующей матрицы temp=new float * [N ]; //выделение памяти для хранения результирующей матрицы for ( i =0; i<N; i++) temp [ i ]=new float [M]; for ( i =0; i<N; i++) //Вычисляем сумму двух матриц for ( j =0; j<M; j++) temp [ i ] [ j ]=A [ i ] [ j ]+B [ i ] [ j ]; return temp; //Возвращаем матрицу как двойной указатель } //функция вычисления разности двух матриц. float **minus_m ( float **A, float **B, int N, int M) { int i, j; float **temp; //указатель для хранения результирующей матрицы temp=new float * [N ]; //выделение памяти для хранения результирующей матрицы for ( i =0; i<N; i++) temp [ i ]=new float [M]; for ( i =0; i<N; i++) //Вычисляем разность двух матриц for ( j =0; j<M; j++) temp [ i ] [ j ]=A [ i ] [ j ]-B [ i ] [ j ]; return temp; //Возвращаем матрицу как двойной указатель } //функция вычисления произведения двух матриц. float **product_m ( float **A, float **B, int N, int M, int L) { int i, j, k; float **temp; //указатель для хранения результирующей матрицы temp=new float * [N ]; //выделение памяти для хранения результирующей матрицы for ( i =0; i<N; i++) temp [ i ]=new float [ L ]; //Вычисляем произведение двух матриц, последовательно формируя все элементы матрицы for ( i =0; i<N; i++) for ( j =0; j<L; j++) //Элемент с индексами i, j — скалярное произведение i-й строки матрицы A for ( temp [ i ] [ j ]=k=0;k<M; k++) //и j-го столбца матрицы B temp [ i ] [ j ]+=A [ i ] [ k ] *B [ k ] [ j ]; return temp; //Возвращаем матрицу как двойной указатель } //функция создаёт динамическую матрицу вещественных чисел размерности N на M, //в этой же функции осуществляется и ввод элементов матрицы float ** create_m ( int N, int M) { int i, j; float **temp; temp=new float * [N ]; for ( i =0; i<N; i++) temp [ i ]=new float [M]; cout<<"Ввод матрицы\n "; for ( i =0; i<N; i++) for ( j =0; j<M; j++) cin>>temp [ i ] [ j ]; return temp; } //функция осуществляет построчный вывод матрицы A(N,M) void output_m ( float **A, int N, int M) { int i, j; //Цикл по строкам. По окончанию вывода всех элементов строки — переход на новую строку. for ( i =0; i<N; cout<<endl, i++) for ( j =0; j<M; j++) //Цикл по переменной j, в котором перебираем строки матрицы cout<<A [ i ] [ j ]<<" \t "; //Вывод очередного элемента матрицы и символа табуляции. } int main ( int arg c, char ** argv ) { float **A, **B, **C, **D, ** result; //указатели для хранения исходных и результирующей матриц int N,M; cout<<" N = "; cin>>N; //Ввод размерностей матрицы cout<<" M = "; cin>>M; //Выделение памяти и ввод матриц A, B, C, D, обращением к функции create_m. A=create_m (N,M); B=create_m (N,M); C=create_m (M,N); D=create_m (M,N); //Вычисление результирующей матрицы. result=product_m ( product_m (sum_m(A, B,N,M),minus_m (C,D,M,N),N,M,N), product_m (sum_m(A, B,N,M),minus_m (C,D,M,N),N,M,N),N,N,N); output_m ( result,N,N); //Вывод результирующей матрицы. return 0; }
Далее без комментариев приведена программа решения задачи 6.9 с помощью динамических матриц и обычных указателей3Обращаем внимание читателя, что при использовании одинарных указателей обращение к элементам матрицы происходит быстрее. При обработке матриц большой размерности (более 1000000 элементов) имеет смысл использовать именно одинарные указатели для хранения и обработки матриц. Это позволит ускорить работу программ на 10-15%.. Рекомендуем читателям самостоятельно разобраться с этой версией программы.
#include <iostream> using namespace std; float *sum_m( float *A, float *B, int N, int M) { int i, j; float *temp; temp=new float [N*M]; for ( i =0; i<N; i++) for ( j =0; j<M; j++) temp [ i *M+j ]=A [ i *M+j ]+B [ i *M+j ]; return temp; } float *minus_m ( float *A, float *B, int N, int M) { int i, j; float *temp; temp=new float [N*M]; for ( i =0; i<N; i++) for ( j =0; j<M; j++) temp [ i *M+j ]=A [ i *M+j ]-B [ i *M+j ]; return temp; } float *product_m ( float *A, float *B, int N, int M, int L) { int i, j, k; float *temp; temp=new float [N*L ]; for ( i =0; i<N; i++) for ( j =0; j<L; j++) for ( temp [ i *L+j ]=k=0;k<M; k++) temp [ i *L+j ]+=A [ i *M+k ] *B [ k*L+j ]; return temp; } float *create_m ( int N, int M) { int i, j; float *temp; temp=new float [N*M]; cout<<"Ввод матрицы\n "; for ( i =0; i<N; i++) for ( j =0; j<M; j++) cin>>temp [ i *M+j ]; return temp; } void output_m ( float *A, int N, int M) { int i, j; for ( i =0; i<N; cout<<endl, i++) for ( j =0; j<M; j++) cout<<A [ i *M+j ]<<" \t "; } int main ( int arg c, char ** argv ) { float *A, *B, *C, *D, * result; int N,M; cout<<" N = "; cin>>N; cout<<" M = "; cin>>M; A=create_m (N,M); B=create_m (N,M); C=create_m (M,N); D=create_m (M,N); result=product_m ( product_m (sum_m(A, B,N,M), minus_m (C,D,M,N),N,M,N), product_m (sum_m(A, B,N,M), minus_m (C,D,M,N),N,M,N),N,N,N); output_m ( result,N,N); return 0; }