Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПЕРОВА САБАЕВА

.pdf
Скачиваний:
190
Добавлен:
11.03.2016
Размер:
1.4 Mб
Скачать

Рис. 9.1. Иллюстрация статического выделения памяти под элементы матрицы

Размерность матрицы не определена перед выполнением программы

Поскольку размеры матрицы не определены до начала выполнения программы, следует использовать динамическое выделение памяти под элементы матрицы, то есть выделение памяти во время выполнения программы.

Если размерность матрицы заранее неизвестна, то для ее описания используется указатель типа указатель на *Тип.

Тип ** имя_матрицы;

В этом случае создается только переменная имя_матрицы типа Тип**. Когда определено число строк (n) и число столбцов (m) матрицы, с помощью операции new выделяется место под n переменных типа Тип*:

имя_матрицы = new Тип*[n];

то есть создается массив имя_матрицы[i]. Затем, для каждого элемента имя_матрицы[i] с помощью той же операции new выделяется место под n элементов типа Тип. Окончательно это может быть оформлено в виде следующего фрагмента:

Тип** имя_матрицы; имя_матрицы = new Тип*[n]; for(i=0; i<m; i++)

имя_матрицы[i] = new Тип[m];

Иными словами, проводятся те операции, которые в первом случае выполняет операционная система.

73

При преобразовании и построении матриц целесообразно выполнять следующие действия:

а) Размерность матрицы и значение ее элементов необходимо читать из файла, так как для ввода с клавиатуры это слишком большой объем информации.

б) Печать матрицы следует оформить в виде отдельной функции, причем оформить шаблонную функцию для того, чтобы можно было печатать матрицы любого типа.

В определении шаблона функций применяется служебное слово template. Для параметризации используется список формальных параметров, который заключается в угловые скобки < >. Каждый формальный параметр шаблона обозначается служебным словом class, за которым следует имя параметра (идентификатор). Каждый параметр обязательно должен присутствовать в заголовке функции. При обращении к функции формальные параметры заменяются фактическими параметрами соответствующего типа.

Листинг 9.1. В программе из файла с именем “input.txt” читаются две матрицы размером 3 × 5. Одна из них вещественная, а другая целочисленная. Причем у вещественной матрицы оставляется только два знака после запятой с округлением.

//L9_1.cpp

#include «stdafx.h» //Файлы, помещенные в данный файл заголовка, будут //предварительно откомпилированы.

#include <fstream> #include <iostream> using namespace std;

//Прототип шаблонной функции можно записать в две строки: template <class pp> //Введение параметров шаблона void print_matrix(pp **a, int n, int m);

int _tmain( )

//Компилятор создаст либо функцию main( ), либо функцию

 

//wmain( ) в зависимости от установок UNICODE.

{

 

setlocale(LC_CTYPE,"russian"); int n,m,i,j;

double **A; //Указатель, который будет связан // с матрицей А.

ifstream ff("input.txt"); ff>>n>>m;

A=new double*[n]; //Идентификация указателя А и запрос

// памяти под n указателей типа double*.

for(i=0; i<n; i++)

A[i]=new double[m]; //Идентификация указателя А[i] и запрос

74

 

//памяти под m указателей типа double.

for(i=0; i<n; i++)

 

for(j=0; j<m; j++)

 

ff>>A[i][j];

 

cout<<"Исходная матрица\n";

 

print_matrix(A,n,m);

 

int **X;

//Указатель, который будет связан с

 

//матрицей X.

X=new int*[n];

//Идентификация указателя X и запрос

 

//памяти под n указателей типа int*.

for(i=0; i<n; i++)

 

X[i]=new int[m];

//Идентификация указателя X[i] и запрос

 

// памяти под m указателей типа int.

for(i=0;i<n;i++)

for(j=0;j<m;j++)

ff>>X[i][j];

ff.close();

cout<<"Исходная целочисленная матрица матрица\n";

print_matrix(X,n,m);

 

cin.get();

 

return 0;

 

}

 

template <class pp>

//Заголовок шаблонной функции

void print_matrix(pp **a,int n,int m)

//можно записать в две строки.

{

 

int i,j;

 

for(i=0;i<n;i++)

 

{

 

for(j=0;j<m;j++)

 

{

 

cout.width(8);

 

int y=int(a[i][j] * 1000);

 

if(y % 10 > 5)

 

y=y/10+1;

else

{

if(y % 10 == 5 && y % 2 != 0) y=y/10+1;

else

y/=10;

}

cout<<double(y) / 100;

}

cout<<'\n';

75

}

}

На рис. 9.2 представлен результат выполнения программы листинга 9.1.

Рис. 9.2. Результат работы программы листинга 9.1

Листинг 9.2. Пусть задана матрица A размером n × n. Необходимо построить матрицу B размером n × n, причем элементы матрицы определяются следующим образом: по индексам i и j строится область , в которой

bij

max a

kl

k ,l

 

. Область показана на рис. 9.3 [26]. Индексы k и l изменяются в

этом случае в следующих пределах: k от 0 до i, а l от j – i + k до j + i - k, причем при проведении сравнения с элементом akl следует проверять, что l лежит в диапазоне от 0 до n-1. Исходные данные находятся в файле “input.txt”, представленном на рис. 9.4.

l

 

k

i,j

Рис. 9.3. Вид области для построения матрицы В

76

Содержимое файла “input.txt”

Рис. 9.4. Исходные данные для построения матрицы В

//L9_2.cpp

 

#include <fstream>

 

#include <iostream>

 

using namespace std;

 

double** bild_matr(double**, int);

//Прототип функции bild_matr( )

void print_matr(double**, int);

//Прототип функции print_matr( )

int main( )

 

{

 

double **A, **B; int i, j, n;

setlocale(LC_CTYPE, "russian"); ifstream fin("input.txt");

fin >> n;

A=new double *[n]; for(i=0;i<n;i++)

A[i]=new double[n]; for(i=0;i<n;i++)

for(j=0;j<n;j++)

fin>>A[i][j]; cout<<"Исходная матрица\n"; print_matr(A,n); B=bild_matr(A,n); cout<<"Полученная матрица\n"; print_matr(B,n);

cin.get(); return 0;

}

void print_matr(double**A, int n)

{

77

int i,j; for(i=0;i<n;i++)

{

for(j=0;j<n;j++)

{

cout.width(5);

cout<<A[i][j];

}

cout<<'\n';

}

}

double** bild_matr(double**A, int n)

{

int i, j, k, l; double **B;

B=new double*[n]; for(i=0;i<n;i++)

B[i]=new double[n]; for(i=0; i<n; i++)

for(j=0; j<n; j++)

{

B[i][j]=A[i][j]; for(k=0; k<=i; k++)

for(l=j-i+k;l<=j+i-k;l++)

if(l>=0 && l<n && B[i][j]<A[k][l]) B[i][j]=A[k][l];

}

return B;

}

Результат выполнения программы листинга 9.2 приведен на рис. 9.5.

Рис. 9.5. Результат работы программы листинга 9.2

78

Листинг 9.3. Пусть задан массив из 64 целых чисел. Будем считать, что одномерный массив состоит из целых чисел от 1 до 64. Построить матрицу размером 8 × 8 из данного одномерного массива, вставляя элементы одномерного массива в матрицу согласно схеме (рис. 9.6) [26].

Рис. 9.6. Схема размещения элементов одномерного массива в матрице

//L9_3.cpp

#include <iostream> using namespace std; int main()

{

int A[8][8], C[64];

int i, j, k, l=0; //Переменная l принимает значение 0 при //движении по схеме на рис. 9.6 вниз и значение 1 //при движении вверх.

for(i=0;i<64;i++)

C[i]=i+1;

for(i=0;i<=7;i++)

{

if(i%2!=0) for(k=0,j=7-i;k<=i;k++,j++)

{

A[k][j]=C[l];

l++;

}

else

for(k=i,j=7;k>=0;k--,j--)

{

A[k][j]=C[l];

79

l++;

}

}

for(i=1;i<=7;i++)

{

if(i%2!=0) for(k=7,j=7-i;j>=0;k--,j--)

{

A[k][j]=C[l];

l++;

}

else

for(k=i,j=0;k<=7;k++,j++)

{

A[k][j]=C[l];

l++;

}

}

for(i=0; i<8; i++)

{

for(j=0; j<8; j++)

{

cout.width(4);

cout<<A[i][j];

}

cout<<'\n';

}

return 0;

}

Результат выполнения программы листинга 9.3 приведен на рис. 9.7.

Рис. 9.7. Результат работы программы листинга 9.3

80

Листинг 9.4. В программе создается квадратная единичная матрица, порядок которой вводится с клавиатуры. Память под элементы матрицы выделяется динамически во время выполнения программы. Динамически выделенная память освобождается оператором delete [24].

//L9_4.cpp

#include "stdafx.h" #include <iostream> #include <locale> using namespace std; void _tmain()

{setlocale (LC_ALL,"Russian"); int n;

int i, j;

cout<<"Введите порядок матрицы: \n"; cin>>n;

float **matr; matr=new float *[n]; if(matr==NULL)

{cout<<"\n Не создан динамический массив" ; return;

}

for(i=0; i<n; i++) {matr[i]=new float [n]; if(matr[i]==NULL)

{cout<<"\n Не создан динамический массив" ; return;

}

for(j=0; j<n; j++) if(i!=j)

matr[i][j]=0;

else

matr[i][j]=1;

}

for(i=0; i<n; i++)

{cout<<"\n Строка "<<i+1<<":"; for(j=0; j<n; j++)

cout<<'\t'<<matr[i][j];

}

for(i=0; i<n; i++) delete matr[i];

delete [] matr;

}

81

Результат выполнения программы листинга 9.4 представлен на рис. 9.8.

Рис. 9.8. Результат работы программы листинга 9.4

Листинг 9.5. В программе создается матрица, элементы которой задаются случайным образом. Память под элементы матрицы выделяется динамически во время выполнения программы. Программа состоит из трех функций: str( ) – функция вычисления среднего значения по строкам матрицы, stlb( ) – функция вычисления среднего значения по столбцам матрицы и функция _tmain( ).

//L9_5.cpp

#include "stdafx.h" #include <stdio.h> #include <locale> #include <iostream> #include <stdlib.h> #include <conio.h> using namespace std;

double* str (int** arr, int n, int m)

{

double* res = new double [n]; double k = 0;

for (int i = 0; i < n; i++)

{

for (int j = 0; j < m; j++)

{

k += arr[i][j];

}

res[i] = k / m; k = 0;

}

return res;

}

double* stlb (int** arr, int n, int m)

82