ВУМЕРНЫЕ МАССИВЫ (МАТРИЦЫ)

Понятие матрицы (двумерного массива)

Определение матрицы. Двумерный массив или матрица — это прямоугольная таблица однотипных элементов, снабженных двумя индексами. Матрица имеет строки (горизонтальные ряды значений) и столбцы (вертикальные ряды значений). Индексация (нумерация) строк и столбцов начинается с нуля. В оперативной памяти матрица хранится по строкам, сначала элементы 0-й строки, затем 1-й строки, 2-й и т. д. Например, матрица А из девяти целочисленных элементов имеет вид, приведенный на рис. 10.1.

Имя

матрицы

А =

Матрица А

Рис. 10.1. Матрица А

Элемент матрицы

Столбец матрицы

Строка матрицы

В оперативной памяти эта матрица будет храниться следующим образом (рис. 10.2).

А [ 1,1] А[1,2] А[1,3] А[2,1] А[2,2] А[2,3] А[3,1] А[3,2] А[3,3]

Рис. 10.2. Матрица А в оперативной памяти

Если в этой матрице поменять местами любые два элемента, то это будет та же самая матрица, расположенная в том же месте опера-тивнои памяти, но с измененными значениями соответствующих элементов.

Атрибуты матрицы. Атрибутами матрицы являются:

  • • имя матрицы;
  • • количество строк ы;
  • • количество столбцов м;
  • • тип элементов матрицы.

Объявление матрицы. Матрицу в программе можно объявить следующим образом:

<тип_элементов> <имя_матрицы>[<число_строк>]

[<число_столбцов>];

где <число_строк> , <число_столбцов> — соответственно количество строк и столбцов в матрице;

<тип_ элементов> — любой тип данных, применяемый в С++.

Например, целочисленная матрица В из 5 строк, 7 столбцов может быть объявлена:

з.Пб В [5] [7] ;

Доступ к элементам матрицы. Доступ к элементам матрицы осуществляется через индексы. Каждый элемент матрицы имеет два индекса: индекс (номер) строки 1, и индекс (номер) столбца з, на пересечении которых он находится:

<элемент_матрицы> = <имя_матрицы>[индекс_строки]

[ индекс_столбца].

Например, элемент, стоящий на пересечении 2-й строки и 1-го столбца матрицы А, обозначается А [ 2 ] [ 1 ].

Формирование матриц и вывод их на экран

Элементы матрицы могут быть сформированы с помощью генератора случайных чисел или введены с клавиатуры. Формирование, ввод и вывод матриц производятся поэлементно с использованием двойного цикла.

Ввод матрицы с клавиатуры. Ввод матрицы с клавиатуры осуществляется построчно: сначала вводятся значения элементов 0-й строки, затем 1-й и т. д.

1. Схема алгоритма

Пояснение. Для ввода элементов матрицы по строкам организованы два цикла: внешний цикл по строкам, внутренний по столбцам .

2. Программа (ввод матрицы по строкам)

#include

const int N=3, M=4; /*объявление констант N — числа строк,

М — числа столбцов матрицы */

int main() {

double А [N] [М] ; //описание вещественной матрицы А

int i, j ;

for (i=0; i//в цикле no строкам

printf("Введите через пробел %d элементов %d строки матрицып" , М, i) ; //вывод приглашения к вводу строки матрицы

for (j = 0; j <М; j + +) //цикл по столбцам

scanf (" % 1 f" , &А [ i ] [ j ] ) ; //ввод элемента матрицы

}

return 0;

}

2. Программа (ввод матрицы по элементам)

#include const int N=3, M=4;

//объявление констант N — числа строк, М — числа столбцов

int main()

{double А [ N ] [ М ] ; //описание вещественной матрицы А

int i, j ;

for (i = 0; i//цикл no строкам

for (j = 0; j //цикл no столбцам

printf("Введите A[ %d][ %d] ",i,j);

//вывод приглашения к вводу элемента матрицы scanf (" % 1 f" , &А [ i ] [ j ] ) ; //ввод элемента матрицы

}

• • •

return 0;

}

Пояснение. Используются 2 оператора цикла for с параметром: внешний цикл (оператор for) с параметром i (начальное значение i равно 0, конечное значение i равно количеству строк в матрице — 1, шаг равен 1), внутренний цикл (оператор for) с параметром j (начальное значение j равно 0, конечное значение j равно количеству столбцов в матрице — 1, шаг равен 1). Переменные i, j являются индексами элементов матрицы (так как индекс элемента матрицы не может быть дробным, то переменные i и j должны иметь тип int).

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

1. Схема алгоритма

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

2. Программа

#include const int N=3, M=4;

//объявление констант N — числа строк, М — числа столбцов

int main() {

double А [N] [М] ; //описание вещественной матрицы А

int i, j ;

• • •

for ( i = 0; i//цикл no строкам

for (j = 0; j //цикл no столбцам

printf("%5.31f ",A[i][j]);

//форматированный вывод элемента матрицы и пробела print f (" ") ; //перевод курсора на начало следующей строки экрана

}

• • •

return 0;

}

Формирование матриц с помощью датчика случайных чисел. Элементы матриц так же, как и элементы одномерных массивов, можно не только вводить с клавиатуры, но формировать с помощью генератора случайных чисел.

1. Схема алгоритма

2. Программа

#include ttinclude #include const int N=5, M=8;

//объявление констант N — числа строк,

//м — числа столбцов

int main() {

int A [N] [M] ; int і, j ;

srand(time(NULL)); for (i=0; i

A[і][j]=rand()%101 -50;

11описание целочисленной матрицы А

//запуск датчика случайных чисел

//цикл по строкам //цикл по столбцам //формирование элемента матрицы

printf("Матрица сформированаХп");

}

Работа с матрицами

Матрицы можно поэлементно складывать, умножать, вычитать, делить и применять к элементам матрицы различные сочетания арифметических операций для получения новой матрицы или массива из элементов матрицы по различным критериям, находить минимальный (максимальный) элемент, сумму, произведение всех элементов, количество каких-либо элементов и т. д. Все операции с матрицами производятся поэлементно с использованием двойного цикла.

Пример программы определения произведения всех элементов матрицы. Ввести с клавиатуры матрицу А[6) [7], вывести ее на экран, найти произведение всех элементов матрицы.

  • 1. Схема алгоритма
  • (см. с. 204—205).

Пояснение. Запись «А16П7]» означает, что в матрице 6 строк и 7 столбцов. С клавиатуры поэлементно вводятся значения элементов матрицы. Затем матрица выводится на экран. В конце программы на экран выводится полученное произведение.

Ввод А[і]Ц]

I

Н+1

Матрица А

Перевод курсора на начало следующей строки экрана

Вывод А[і][П

2. Программа

#include const int N=6, M=7; int main() {

double A[N][M]; int i, j ;

for (i = 0; i

{printf("Введите A[ %d][ %d] scanf("%lf",&A[i][j]);

//цикл no строкам //цикл no столбцам

и

' •

,i,3)

/

printf("Матрица Ап");

for (i = 0; i//цикл no строкам

for (j = 0; j //цикл no столбцам

printf("%5.3If ",A[i][j]);

//форматированный вывод элемента матрицы и пробела print f (" ") ; //перевод курсора на начало следующей строки экрана

}

Р=1; //задание начального значения произведения (Р-1)

for (i = 0; i//цикл no строкам

for (j = 0; j <М; j + +) //цикл по столбцам

P=P*A[i] [j] ; //умножение старого значения Р на элемент матрицы

printf("P=%lf ",Р); getchar(); return 0;

}

Пояснение. В программе используются четыре переменные: вещественная матрица А из б строк и 7 столбцов (размеры матрицы объявлены как константы N и м для того, чтобы проще было модифицировать программу при изменении размеров матрицы); i, j — параметры циклов (индексы элементов матрицы) объявлены как переменные типа int; Р — произведение всех элементов (объявлена как переменная типа double, так как тип double имеет более широкий диапазон возможных значений).

Для решения задачи используются трижды два вложенных оператора for: ввод с клавиатуры значения элементов матрицы, вывод матрицы на экран, вычисление произведения всех элементов матрицы. В матрице А б строк, 7 столбцов, поэтому в каждом двойном цикле внешний цикл (по строкам) выполняется N=6 раз, а внутренний цикл (по столбцам) выполняется м=7 раз.

Примечание. В рассмотренной задаче можно объединить ввод матрицы с клавиатуры и вычисление произведения всех элементов матрицы в один цикл, используя составной оператор:

Р=1;

for (i=0; i< N; i++) for (j = 0; j < K; j++)

{printf("Введите A[%d] [%d]=",i,j) ; scanf("%lf",&A[i] [j] ) ;

P=P*A[i,j];

}

printf("Матрица A ");

Пример программы определения суммы элементов главной и произведения элементов побочной диагоналей матрицы. Сформировать матрицу С[3][3] случайным образом. Вывести ее на экран. Найти сумму элементов главной диагонали матрицы и произведение элементов побочной диагонали матрицы (рис. 10.3).

  • 3
  • 5

Матрица с — квадратная, размерности ыхц (N=3 в нашем примере). Элементы С [0, 0] =5, С[1,1]=11, С [2,2] =8 расположены на главной диагонали матрицы С, для этих элементов номер строки равен номеру столбца, т. е. і=:і. Элементы с [0,2] =6, С [1,1] =11, С [2,0] =3 расположены на побочной диагонали матрицы с, для этих элементов (номер строки + номер столбца)^- т. е. 1+? =2 в нашем случае.

1. Схема алгоритма

Рис. 10.3. Матрица и ее диагонали

і=і+1

Матрица С

Перевод курсоре на начало следующей строки

Вывод с:[і]? ]

і

]=і+1

Пояснение. Для решения задачи необходимо сформировать с помощью генератора случайных чисел квадратную матрицу 3-го порядка (матрица С из трех строк, трех столбцов) и вывести ее на экран. Затем задаются начальные значения сумме (3=0) и произведению (Р=1) и перебираются все элементы матрицы (по строкам). Если для элемента Су выполняется условие главной диагонали 0=)), то он прибавляется к уже имеющейся сумме таких элементов. Если для элемента Су выполняется условие побочной диагонали (но=Ы-1), то он умножается на уже имеющееся произведение таких элементов.

2. Программа. 1-й способ решения

#include

#include

#include

const int N=3; //объявление константы N — числа строк

//и числа столбцов

int main() {

int C[N][N];

int i, j ;

double S,P;

srand(time(NULL));

for (i=0; i

for (j=0; j

C[i][j]=rand()%101 -50; printf("Матрица C "); for (i=0; i

}

S = 0;

P-1;

for (i=0; i

{ if (i ==j)

S = S+C [ і] [j] ; if ((i+j) == N-l) P=P*C[i][j];

//задание начального значения суммы (Б=Ъ) //задание начального значения произведения (*9=1)

//цикл по строкам //цикл по столбцам //если элемент на главной диагонали //прибавляем его к сумме //если элемент на побочной диагонали //умножаем его на произведение

}

printf("S=%lf P=%lf ",S,P); getchar(); return 0;

Пояснение. Матрица С — квадратная (число строк равно числу столбцов), поэтому объявлена только одна константа (порядок матрицы). В программе используются пять переменных: С — квадратная целочисленная матрица третьего порядка; i, j — параметры цикла for (индексы элементов матрицы); S — сумма элементов главной диагонали типа double; Р — произведение элементов побочной диагонали типа double. В первом двойном цикле происходит формирование элементов матрицы с помощью генератора случайных чисел. Во втором двойном цикле — вывод матрицы на экран. В третьем двойном цикле — вычисление суммы и произведения по диагоналям матрицы.

3. Программа. 2-й способ решения

#include

#include

#include

const int N=3 ; //объявление константы N — числа строк

//и числа столбцов

int main() {

int С [N] [N] ;

int i, j ;

double S,P;

srand(time(NULL));

for (i=0; i

for (j=0; j

C[i][j]=rand()%101 -50; printf("Матрица C "); for (i=0; i

}

S=0; //задание начального значения суммы (S=0)

Р=1; //задание начального значения произведения (Р=1)

for (i = 0; i//цикл no строкам

{ S=S+C[i][i]; //прибавляем к сумме элемент на главной диагонали

Р=Р * С [ i ] [N-1-i]; //умножаем произвед. на элем, на побочн. диагонали

}

printf("S=%lf P=%lf ",S,P); getchar(); return 0;

}

Пояснение. Матрица С — квадратная (число строк равно числу столбцов), поэтому объявлена только одна константа (порядок матрицы). В программе используются пять переменных: С — квадратная целочисленная матрица третьего порядка; i, j — параметры цикла for (индексы элементов матрицы); S — сумма элементов главной диагонали типа double; Р — произведение элементов побочной диагонали типа double. В первом двойном цикле происходит формирование элементов матрицы с помощью генератора случайных чисел. Во втором двойном цикле — вывод матрицы на экран. В третьем одинарном цикле — вычисление суммы и произведения по диагоналям матрицы.

Поиск максимального (минимального) элемента матрицы и определение его координат (индексов)

Алгоритм поиска максимального элемента в матрице и определения его координат полностью аналогичен алгоритму поиска минимального элемента в матрице и определения его координат.

Пример программы поиска максимального элемента в матрице и определения его координат. Сформировать матрицу А произвольной размерности. Вывести матрицу. Найти ее максимальный элемент и его координаты.

1. Схема алгоритма

Матрица А

Пояснение. Введем рабочие переменные: Мах — для хранения текущего значения максимального элемента матрицы; imax — номер строки текущего максимального элемента; jmax — номер столбца текущего максимального элемента. Предположим, что 0-й элемент 0-й строки матрицы — максимальный. Запомним его значение в переменной Мах; в переменной imax запомним значение «0» — индекс (номер строки) предполагаемого максимального элемента; в переменной jmax запомним значение «0» — индекс (номер столбца) предполагаемого максимального элемента. Далее первый элемент 0-й строки матрицы сравниваем со значением Мах. Если первый элемент больше Мах, то запишем его значение в переменную Мах, номер строки 1-го элемента («0») запомним в переменной imax, а номер столбца («1») — в переменной jmax. Переходим к следующему элементу 0-й строки матрицы. Если первый элемент не больше Мах, то сразу переходим к следующему элементу 0-й строки матрицы, не изменяя значений переменных Max, imax, jmax. Эту процедуру повторяем со всеми элементами 0-й строки, потом переходим к элементам 1-й строки и т. д. Таким образом, после прохода по всем строкам матрицы в переменной Мах будет находиться значение максимального элемента матрицы, а в imax и jmax — соответственно номер строки и номер столбца максимального элемента матрицы.

2. Программа

#include

#include

#include const int N=7, M=10; int main() { int A [N] [M] ;

int i, j, Max, imax, jmax; srand((unsigned int)time(NULL)); for (i=0; i

А[i][j]=rand()%101 -50; printf("Матрица A "); for (i=0; i

{

for (j=0; j

}

Max=A[0][0];

//присвоить перем. Max значение элем, матрицы с координатами 0,0 imax=0; //присваивание 0 номеру строки предполагаемого максимума j max=0; //присваивание 0 номеру столбца предполагаемого максимума

for (i = 0; i//цикл no строкам

for (j = 0; j <М; j + +) //цикл по столбцам

if (А[i][j]>Мах)

//если текущий элемент матрицы больше предполагаемого максимума {Мах=А [ i ] [ j ] ; //меняем предполагаемый максимум

imax=i; //номер строки предполагаемого максимума

j max=j ; //номер столбца предполагаемого максимума

}

printf("Max=%d imax=%d jmax=%d ",Max,imax,jmax); getchar(); return 0;

}

Пояснение. В программе используются шесть переменных: А — целочисленная матрица; i, j — параметры цикла for, Мах — максимальный элемент матрицы; imax — номер строки максимального элемента; jmax — номер столбца максимального элемента. Переменные i, j, imax, jmax имеют тип int. Тип переменной Мах определяется типом элементов матрицы (в данном случае int).

Примечание. Нахождение минимального элемента матрицы и его координат аналогично поиску максимального элемента, но значения переменных Min (текущий минимальный элемент), imin, jmin (индексы текущего минимального элемента) переопределяются, если некоторый элемент массива меньше текущего минимального.

Формирование одномерных массивов из элементов матриц

Пример программы формирования одномерных массивов из сумм положительных элементов каждой строки матрицы. Сформировать матрицу С{7,8}. Вывести ее. Сформировать одномерный массив В из сумм положительных элементов каждой строки матрицы. Вывести массив В на экран.

1. Схема алгоритма

^ Начало ^

Инициализация генератора случайных чисел

Формирование элемента С[і]Ц]

Н+1

Матрица С

Перевод курсора на начало следующей строки

Вывод С[ГЩ]

і=і+1

I

Н+1

В[Г

1=8

ы

+ 1

Вывод В[1]

=1=

И+1

  • —Г"
  • (

Конец

)

Пояснение. Матрица С формируется с помощью генератора случайных чисел и выводится на экран в одном цикле. Затем формируется массив М. Для этого матрица С просматривается по строкам (внешний цикл по строкам — по i). Для каждой строки выполняются 3 действия:

  • • задается начальное значение суммы положительных элементов /-й строки (S=0);
  • • вычисляется сумма положительных элементов /-й строки (внутренний цикл по j);
  • • вычисленная сумма для /-й строки записывается в элемент массива В с индексом i (массив В формируется по строкам матрицы, поэтому индексы элементов массива совпадают с индексами строк матрицы: сумма положительных элементов 0-й строки записывается в В0, 1-й строки — в В[ и т. д.)
  • 2. Программа

#include

#include ttinclude const int N=7, M=8; int main() {

int C [N] [M] ; int i,j; double S, B[N]; srand(time(NULL)); for (i=0; i

C[i][j]=rand()%101 - 50; printf("Матрица C "); for (i=0; i

}

for(i = 0;i/в цикле no строкам

S=0; //зад. нач. значения сумме положит, элементов х-й строки (S=0) for(j=0; j <М; j++) //в цикле по столбцам

if (С [ i ] [ j ] >0) //если элемент матрицы больше 0

S=S+C[i] [j] ; //прибавляем элемент матрицы к старому значению S

В [ i ] = S; //присвоение х -му элементу массива В значения S

}

printf("Массив Вп");

for (i=0; i

}

Пояснение. В программе используются пять переменных: С — целочисленная матрица из семи строк, восьми столбцов; в — вещественный массив из семи элементов (длина массива определяется числом строк в матрице, тип элементов определяется типом элементов матрицы); i, j — параметры цикла и индексы элементов матрицы (типа int), S — текущее значение суммы положительных элементов в каждой строке матрицы. В первом двойном цикле происходит формирование элементов матрицы С. Во втором цикле происходит вывод на экран элементов матрицы С. В третьем цикле происходит вычисление суммы положительных элементов в каждой (i-й) строке матрицы и запись полученного значения в элементы массива в (в [ i ]). В конце программы на экран выводится массив в.

Пример программы формирования одномерного массива из минимальных элементов каждого столбца матрицы. Сформировать матрицу Н{ 12,5}. Вывести ее. Сформировать одномерный массив F из минимальных элементов каждого столбца матрицы. Вывести массив на экран.

2. Программа

#include

#include

#include const int N=12, M=5; int main() { int H [N] [M] ; int i , j ; int min, F[M]; srand(time(NULL)); for (i=0; i

H[i][j]=rand()%101 - 50; printf("Матрица H "); for (i=0; i

}

for (j = 0; j <М; j++){ //в цикле по столбцам

min=H [ 0 ] [ j ] ; //приев, нач. знач. предполагаемому миним. в столбце

for (i = 0; i//в цикле по строкам

if (Н[i][j]

//если элемент матрицы меньше предполагаемого минимума min=H [ i ] [ j ] ; //меняем предполагаемый минимум

F [ j ] =min; //присваивание j -му элементу массива F значения min

}

printf("Массив F "); for (j=0; j

}

Пояснение. В программе используются пять переменных: Н — целочисленная матрица; F — одномерный массив (длина массива F и тип его элементов определяются соответственно числом столбцов и типом элементов матрицы Н); i, j — параметры цикла и индексы элементов; min — текущее значение минимального элемента j-ro столбца. Формирование элементов матрицы и вывод матрицы на экран происходит в первых двух циклах. При формировании массива F матрица рассматривается по столбцам (внешний цикл по j, внутренний цикл по i), для каждого столбца выполняются три действия:

  • • 1-й элемент j-ro столбца принимается за минимальный (min=H [ 0 , j ]);
  • • происходит поиск минимального элемента в одномерном мае-сиве (j-й столбец рассматривается как одномерный массив, изменяется только индекс i);
  • • найденный минимальный элемент j -го столбца записывается в элемент массива F с индексом j (F [ j ] =min).

Представление двумерного массива (только для И-32,33)

Представление двумерного массива (матрицы). Матрица (двумерный массив) в языке С++ рассматривается как одномерный массив, элементами которого являются одномерные массивы — строки матрицы. Так как имя одномерного массива (строки матрицы) является указателем на массив, то элементами матрицы как одномерного массива являются адреса строк матрицы (рис. 10.4).

Адрес

М[0][0]

М[0][1]

М|0][2]

. . .

М[0][К]

М[1][0]

М[1][1]

М[1][2]

М[1][К]

Адрес

N-й

М[2][0]

М[2][1]

М[2][2]

М[2][К]

M[N]f0]

M[N][1]

M[N][2]

. . .

M[N]fK]

Имя

матрицы

(М)

Адрес массива указателей на строки матрицы

0- й

строки

(М[0])

Адрес

1- й

строки

(М[1])

Адрес

2- й

строки

  • (М[2]) строки
  • (M[N])

Рис. 10.4. Представление матрицы как одномерного массива

Адреса элементов матрицы. Из рис. 10.4 видно, что имя матрицы содержит адрес массива указателей (адресов) на строки матрицы. Элементами безымянного массива указателей на строки являются адреса соответствующих строк матрицы. По адресам (указателям) строк можно получить доступ к каждой строке матрицы (табл. 10.1). Так как в имени матрицы хранится только адрес массива указателей на строки, то для получения адреса каждой строки необходимо выполнять разыменование указателя — «имя матрицы + номер строки».

Зная адрес каждой строки матрицы, можно вычислить адрес каждого элемента этой строки (табл. 10.2).

Доступ к элементам матрицы. Используя операцию разыменования, можно по адресу элемента, стоящего на пересечении і-й строки и j-го столбца — * (Имя_матрицы + i)+j получить его значение — * ( * (Имя_матрицы + і ) + j ) (второй столбец табл. 10.3). Для матриц существует и другой, более удобный способ записи операции разыменования — Имя_матрицы [ і ] [ ;ї ] (третий столбец табл. 10.3). Например, для матрицы м из N строк и К столбцов, представленной на рис. 10.4, значение элемента матрицы, стоящего на пересечении і-й строки и :)-го столбца, можно получить двумя тождественными способами — *(* (м+і ) +j ] и м[і] [з ] . Любую запись доступа к элементу матрицы А [ 3 ] [ 5 ] компилятор автоматически преобразует к виду *(*(А+3) + 5), но так как первый вариант записи более наглядный, то на практике можно пользоваться им.

Таблица 10.1. Вычисление адресов строк в матрице

Адреса строк в матрице

Формулы для вычисления адресов

Формулы для вычисления адресов с использованием операции разыменования

Формулы для вычисления адресов с использованием доступа[ ]

Адрес 0-й строки матрицы

Адрес массива указателей на строки + 0

*(Имя_матрицы + 0)

Имя_матрицы[0]

Адрес 1-й строки матрицы

Адрес массива указателей на строки + 1

*(Имя_матрицы + 1)

Имя_матрицы[1]

Адрес 2-й строки матрицы

Адрес массива указателей на строки + 2

*(Имя_матрицы + 2)

Имя_матрицы|2|

Адрес і-й строки матрицы

Адрес массива указателей на строки + і

*(Имя_матрицы +1)

Имя_матрицы[П

Таблица 10.2. Вычисление адресов элементов в і-й строке матрицы

Адреса элементов в /-й строке матрицы

Формулы для вычисления адресов

Формулы для вычисления адресов

Формулы для вычисления адресов

Адрес

0-го элемента

Адрес і-й строки -г 0

*(Имя_матрицы + 0+0

И мя_матрицы [ і |+0

Адрес

1-го элемента

Адрес і-й строки + 1

*(Имя_матрицы + 0+1

Имя_матрицьі[і]+1

Адрес

2-го элемента

Адрес і-й строки + 2

*(Имя_матрицы + 0+2

И мяматри цы [ і ]+2

Адрес

І-го элемента

Адрес і-й строки +)

*(Имя_матрицы + і)+І

Имя_матрицьі[і]+і

Таблица 10.3. Определение значений элементов в і-й строке матрицы

Значения

элементов матрицы

Формулы для определения значений

Формулы для определения значений

Значение 0-го элемента

*(*(Имя_матрицы + 0+0)

Имя_матрицьі[і][0]

Значение 1-го элемента

*(*(Имя_массива + 0+1)

Имя_матрицьі[і] [ 1 ]

Значение 2-го элемента

*(*(Имя_массива + і)+2)

Имя_матрицьі[і][2]

Значение у-го элемента

*(*(Имя_массива + і)+0

И мя_матри цы [ і 11 і |

Представление статического двумерного массива (только для И-32,33)

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

В оперативной памяти статическая матрица хранится по строкам, сначала элементы 0-й строки, затем 1-й строки, 2-й и т. д. Например, описанная ранее матрица А из 10 целочисленных элементов (см. рис. 10.1) в оперативной памяти будет храниться следующим образом (рис. 10.5).

А[ 0,0] А [ 0,1 ] А[0, 2] А [ 1,0 ] А[1,1] А[1,2] А [2, 0] А [ 2, 1 ] А [2,3 ]

Рис. 10.5. Матрица А в оперативной памяти

Так как статическая матрица хранится по строкам, то можно рассчитать адрес каждой строки в байтах (табл. 10.4). В приведенных формулах sizeof — операция определения количества байтов в значении типа, указанного в скобках, например, sizeof (int) =4, sizeof (double) =8. Отдельного массива указателей на строки статической матрицы не существует, в качестве значений указателей на строки используются значения, вычисленные по формулам таблицы

10.4. Полученные значения указателей, например, можно вывести на экран.

Таблица 10.4. Вычисление адресов строк в статической матрице в байтах

Адреса строк в матрице в байтах

Формулы для вычисления адресов строк матрицы в байтах

Адрес 0-й строки матрицы

Адрес матрицы0*+<число столбцов>*5ІгеоГ(<тип элементов матрицы>)

Адрес 1-й строки матрицы

Адрес матрицы 1*+<число столбцов>*8ІгеоГ(<тип элементов матрицы>)

Адрес 2-й строки матрицы

Адрес матрицы2*+<число столбцов>*5ігеоГ(<тип элементов матрицы>)

Адрес і-й строки матрицы

Адрес матрицьіі*+<число столбцов>*$ігеоГ(<тип элементов матрицы>)

Адрес каждого элемента матрицы рассчитывается по формулам, представленным в табл. 10.5.

Таблица 10.5. Вычисление адресов элементов /-й строки в статической матрице в байтах

Адреса элементов

1-й строки матрицы в байтах

Формулы для вычисления адресов элементов /-Й строки матрицы в байтах

Адрес 0-го элемента

Адрес матрицьіі*+<число столбцов>*5ІгеоГ(<тип элементов матрицы>)+0*5^еоГ(<тип элементов матрицы>)

Адрес 1-го элемента

Адрес матрицьіі*+<число столбцов>*5ІгеоГ(<тип элементов матрицьі>)+1*8І2ЄоГ(<тип элементов матрицы>)

Адрес 2-го элемента

Адрес матрицьіі*+<число столбцов>*5ІгеоГ(<тип элементов матрицьі>)+2*8І2еоД<тип элементов матрицы>)

Адрес і-го элемента

Адрес матрицьіі*+<число столбцов>*8ІгеоД<тип элементов матрицьі>)+і*8І2ЄоГ(<тип элементов матрицы>)

Динамические двумерные массивы (только для И-32,33)

Если в программе возникает необходимость использовать матрицу (двумерный массив), количество строк и столбцов в которой заранее неизвестно, то определить ее статическим способом невозможно, так как компилятору неизвестно количество строк и столбцов матрицы и, соответственно, неизвестен размер области, которую необходимо зарезервировать. И следующая последовательность операторов

ігШ п; іґШ к; п = 3 ; к= 3;

ігШ А [п] [к] ;

//описание переменной п — числа строк матрицы //описание переменной к — числа столбцов матрицы //присваивание числу строк матрицы значения 3 //присваивание числу столбцов матрицы значения 3

//описание целочисленной матрицы А

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

Таким образом, при использовании матриц, количество строк и столбцов в которых заранее неизвестно, приходится пользоваться динамически распределяемой памятью, а полученные таким образом матрицы называются динамическими.

Для динамических матриц память выделяется в программе в тот момент, когда это необходимо программисту, и количество строк и столбцов можно либо ввести с клавиатуры, либо вычислить по определенному алгоритму. При этом выделяется область памяти, которая не имеет своего имени (неименованная область памяти). Доступ к выделенной области возможен только через указатель — имя динамической матрицы, который содержит номер первого байта выделенной области памяти, и является указателем на матрицу.

Объявление динамических массивов. Динамические матрицы являются одномерными динамическими массивами, элементами которых являются указатели на одномерные динамические массивы, и объявляются следующим образом:

<тип_элементов_матрицы> * *<имя_матрицы>;

Здесь <тип_элементов_массива> может быть любым допустимым в языке С++ типом;

<имя_матрицы> — является указателем, т. е. может содержать адрес некоторой области памяти, в которой может находиться массив указателей (адреса начала каждой строки матрицы) на заданный тип.

Например, в следующем фрагменте программы

п; /1описание целой переменной — числа строк матрицы

з-гЩ к; //описание целой переменнойчисла столбцов матрицы

**М; //указатель на одномерный массив указателей

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

Выделение и освобождение памяти для динамической матрицы. Для выделения памяти под динамическую матрицу необходимо воспользоваться представлением матрицы как одномерного массива указателей (см. рис. 10.4). То есть сначала надо зарезервировать память под одномерный массив указателей на строки с помощью оператора

<имя_матрицы> = new <тип_элем_масси-ва*>[<кол-во_строк_матрицы>];

При этом получится распределение памяти, показанное на рис. 10.6.

Например, фрагмент программы

printf("Введите число строк матрицы ");

//вывод приглашения к вводу числа строк матрицы Бсап? (" %сГ , &п) ; //ввод числа строк матрицы

М=пелг іпЬ* [п] ;

//выделение памяти под п указателей на целочисленные строки матрицы М

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

Адрес 0-й строки (M[()J)

Имя матрицы (указатель на массив (адрес массива) указателей на строки матрицы )

Адрес 1-й строки (М[1]) Адрес 2-й строки (М[2])

Адрес п-й строки (М[п])

Рис. 10.6. Распределение памяти после выделения памяти под одномерный массив

указателей на строки

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

for (і = 0; і<число_строк_матрицьі; і++)

<имя_матрицы>[і]=new <тип элементов матрицы>[коли-чест-во_столбцов_матрицы]

Например, фрагмент программы:

...printf("Введите число столбцов матрицы ');

//вывод приглашения к вводу числа столбцов матрицы scanf (" %d" , &k) ; //ввод числа столбцов матрицы

for(i = 0; i//в цикле

М [ i ] =new int [k] ; // выделение памяти под i-ю строку матрицы М

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

Когда память, выделенная под динамическую матрицу, больше не нужна, ее следует освободить. Делается это в порядке, обратном процессу выделения памяти под матрицу: сначала освобождается память под строки матрицы

for (і = 0; і<число_строк_матрицьі; і++) delete []имя_динамической_матрицы[і];

Пример.

for (i = 0; i//в цикле

delete []M[i];

//освобождаем память, выделенную под i -ю строку матрицы М

Далее необходимо освободить память, выделенную под массив указателей на строки матрицы

delete []имя_динамической_матрицы;

Пример.

delete []М;

//освобождение памяти, выделенной под массив указателей

//на строки матрицы

Решение задач с использованием динамических матриц. Рассмотрим решение задач с использованием динамических матриц.

Пример. Ввести с клавиатуры количество строк и столбцов целочисленной матрицы. Сформировать матрицу с помощью датчика случайных чисел. Вывести матрицу на экран. Найти произведение всех элементов матрицы.

#include ttinclude

#include int main() {

int **X = NULL; //описание и инициализация указателя на матрицу X int n; //описание переменной n — числа строк матрицы

int к; //описание переменной к — числа столбцов матрицы

int i,j; double Pr; srand(time(NULL)) ;

printf("Введите число строк матрицы n = ");

scanf("%d",&n);

printf("Введите число столбцов матрицы k = "); scanf("%d",&k);

X=new int * [ n ] ; //выделение памяти под указатели на строки матрицы for (i = 0; i//в цикле по строкам

X [i] =new int [k] ; //выделяем память под i -ю строку матрицы

for (i = 0; i//в цикле no строкам

for (j=0; j//в цикле no столбцам

X [ i ] [ j ] = rand () % 101 - 5 0; //формирование элемента матрицы

printf("Матрица X ");

і + +) { //цикле no строкам

for (i= for (j= printf( printf( }

Pr=l ; for (i= for (j= Pr=Pr*X printf( %lf ", getchar return }

0; i

j + +) I/в цикле no столбцам

" %4d " ")

, X [ і ] [ j ] ) ; //вывод элемента матрицы

//перевод курсора на начало следующей строки экрана

//присвоение начального значения произведения (Рг) 0; і<п; і + +) //в цикле по строкам

0; j //в цикле по столбцам

[ і ] [ j ] ; //умножение старого значения Рг на элемент матрицы "Произведение всех элементов массива Рг =

Рг) ;

О ;

0;

Тесты

  • 1. Элемент матрицы А [ 4 ] [ 2 ] находится на пересечении:
    • а) 2-й строки и 4-го столбца;
    • б) 4-й строки и 2-го столбца;
    • в) правильного ответа нет.
  • 2. В каком диапазоне будут находиться значения элементов матрицы А?

for (i=0; i<3; i++) for (j = 0; j<5; j++)

A[і][j]=rand()%300-200;

  • • • •
  • а) от 0 до 300;
  • б) от 0 до 200;
  • в) от -200 до 1010.
  • 3. В каком порядке производится заполнение значениями матрицы А размером 10x10 в следующем фрагменте программы?

for ( і = 0; і<10; І + +) for (j =10; j >=0; j--)

A[i][j]=rand()%100;

  • а) по строкам справа налево;
  • б) по столбцам снизу вверх;
  • в) правильного ответа нет.
  • 4. В каком порядке производится заполнение значениями матрицы А размером 10x10 в следующем фрагменте программы?
  • • • •

for ( j = 0; j <10; j++) for (i=10; i>=0; i--) do A[i] [j]=rand()%100;

  • • • •
  • а) по строкам справа налево;
  • б) по столбцам снизу вверх;
  • в) правильного ответа нет.
  • 5. Что делает следующий фрагмент программы, если дана матрица а размером 3x5?
  • • • •
  • S : = 0 ;

for (i=0; i<3; i++) for (j = 0; j<5; j++) if (A[i][j]<0)

S=S+A[i][j];

  • а) присваивает переменной Б значение суммы всех элементов матрицы А;
  • б) присваивает переменной Б значение суммы отрицательных элементов матрицы А;
  • в) правильного ответа нет.
  • 6. Что делает следующий фрагмент программы, если дана матрица а размером 3x5?

М=А[0][0]; for (i=0; i<3; i++) for (j = 0; j<5; j++) if (A[і][j]

  • а) присваивает всем элементам матрицы А значение переменной м;
  • б) присваивает переменной м значение наименьшего элемента матрицы А;
  • в) правильного ответа нет.
  • 7. Дана матрица

41

-3,14

17 N

н =

-13

0

9,8

V113

53,2

-37,8,

Какой массив К сформируется в результате выполнения следующего фрагмента программы?

• • •

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

{ M=H [і] [0] ;

for (j=l; j<3; j++) if (H[і][j]>M)

Then M:=H[і,j];

К[і]=M;

}

  • • • •
  • а) К = (113 53.2 17);
  • б) К = (17 10.8 113);
  • в) К = ( - 3.14 -13 -37.8).
  • 8. Что делает следующий фрагмент программы, если дана матрица н размером 12x5?
  • • • •

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

{ P=l;

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

P=P*H[i,j];

К [ j ] = P;

}

  • • • •
  • а) присваивает переменной P значение произведений всех элементов матрицы Н;
  • б) формирует массив К из произведений всех элементов каждого столбца матрицы Н;
  • в) формирует массив К из произведений всех элементов каждой строки матрицы Н.

Задания

  • 1. Ввести с клавиатуры матрицу ^{7,10}. Вывести ее на экран. Найти сумму отрицательных элементов матрицы, произведение положительных элементов, количество ненулевых элементов.
  • 2. Ввести с клавиатуры матрицу #{5,7} построчно. Вывести ее на экран. Все ненулевые элементы заменить обратными по величине (обратным для числа а является число 1/а) и противоположными по знаку. Вывести измененную матрицу на экран.
  • 3. Сформировать матрицу #{12,12}. Вывести матрицу. Заменить нулями все элементы, расположенные на главной диагонали и выше ее. Вывести измененную матрицу.
  • 4. Ввести матрицу Г{4,4}. Вывести ее на экран. Вычислить произведение положительных элементов, лежащих под главной диагональю.
  • 5. Сформировать случайным образом целочисленную матрицу Nх N. Сформировать два одномерных массива А и В: в массив А записать элементы матрицы, расположенные на главной диагонали и ниже нее, в массив В — элементы, лежащие на побочной диагонали и ниже нее. Вывести оба массива на экран теми же цветами, что главная и побочная диагональ матрицы соответственно.
  • 6. Ввести с клавиатуры матрицу С{4,3}. Вывести ее на экран. Создать из матрицы С матрицу Р таким образом, что все столбцы матрицы С станут строками матрицы Р, а все строки — столбцами матрицы Р в том же порядке (1-й столбец в С станет первой строкой в Р), т. е. Р=СТ. Вывести матрицу Р.
  • 7. Ввести с клавиатуры матрицу М{3,4} и число #. Вывести ее на экран. Определить номер 1-го элемента, большего #, и посчитать сумму элементов, ему предшествующих, если считать от левого верхнего угла матрицы построчно.
  • 8. Латинским квадратом порядка N называется квадратная таблица размером Nx N, каждая строка и каждый столбец которой содержат все числа от 1 до N. Для заданного N (вводится с клавиатуры) в матрице /.{#,#} построить латинский квадрат порядка N.
  • 9. Составить программу упорядочения по возрастанию элементов каждой строки матрицы С (размеры матрицы произвольные, задаются с клавиатуры).
  • 10. Сформировать матрицу #{12,15}. Поменять местами минимальный и максимальный элементы. Вывести матрицу до замены и после.
  • 11. Сформировать матрицу А{6,7}. Вывести ее на экран. Найти произведение элементов строки, в которой находится элемент с наибольшим

значением.

  • 12. Ввести матрицу Л{7,8}. Сформировать три одномерных массива: В — из максимальных элементов строк матрицы А; С — из минимальных элементов столбцов матрицы А; О — из средних арифметических элементов строк матрицы А.
  • 13. Сформировать вещественную матрицу Л{6,10}. Найти среднее арифметическое наибольшего и наименьшего значений ее элементов, расположенных ниже главной диагонали.
  • 14. Сформировать матрицу Л^{5,7}. Вывести матрицу. Найти и вывести значение минимального элемента. Вывести координаты всех минимальных элементов матрицы и их количество.
  • 15. Дана целочисленная матрица 10 х 10. Сформировать одномерный массив, состоящий из сумм отрицательных элементов строк, и одномерный массив, состоящий из сумм отрицательных элементов столбцов.
  • 16. Сформировать матрицу #{10,10}. Все элементы с наибольшим значением в данной матрице заменить нулями, если эти элементы не принадлежат 1 -й или последней строкам. Вывести матрицу до и после замены.
  • 17. Используя генератор случайных чисел, сформировать матрицу //{10,8} из вещественных чисел. Вывести матрицу N. Получить новую матрицу С из матрицы Н путем деления всех элементов матрицы Н на ее наибольший по модулю элемент.
  • 18. Дана целочисленная матрица 8x8. Найти ее минимальный элемент и сумму элементов заштрихованной области.

19. Дана целочисленная матрица 8x8. Найти ее минимальный элемент и сумму элементов заштрихованной области.

  • 20. Дана целочисленная матрица размерностью М х К. Найти минимальное значение для верхней половины матрицы и максимальное значение для нижней половины.
  • 21. Дана целочисленная матрица 8x8. Найти ее максимальный элемент и сумму элементов заштрихованной области.
  • 22. Ввести символьную матрицу 5x7. Сформировать одномерный массив из сумм кодов символов каждой строки и одномерный массив из сумм кодов символов каждого столбца.
  • 23. Дана целочисленная матрица М х К. Сформировать новую матрицу путем прибавления в каждой строке к каждому элементу исходной матрицы максимального значения элемента данной строки.
  • 24. Дана матрица 7x6. Сформировать одномерный массив, содержащий сумму максимального и минимального элементов каждой строки. Вывести матрицу и массив на экран.
  • 25. Ввести символьную матрицу 5x7. Сформировать одномерный массив из минимальных кодов символов каждой строки и одномерный массив из максимальных кодов символов каждого столбца.
  • 26. Дана целочисленная матрица М х К. Сформировать новую матрицу путем прибавления в каждом столбце к каждому элементу исходной матрицы минимального значения элемента данного столбца.
  • 27. Дана матрица 7x7. Сформировать одномерный массив, содержащий элементы главной диагонали исходной матрицы. Вывести матрицу и массив на экран.
  • 28. Сформировать вещественную матрицу А{6,6}. Найти среднее арифметическое наибольшего и наименьшего значений ее элементов, расположенных ниже главной диагонали.
  • 29. Сформировать матрицу ^{5,7}. Вывести матрицу. Сформировать одномерный массив из минимальных элементов каждой строки матрицы.
  • 30. Ввести с клавиатуры матрицу (?{4,5}. Вывести ее на экран. Найти среднее арифметическое элементов каждой строки матрицы и вычесть его из элементов этой строки.
  • 31. Сформировать вещественную матрицу 14,14}. Построить одномерный массив Р по правилу: если в /-й строке матрицы элемент, принадлежащий главной диагонали, отрицателен, то элемент массива Р, равен сумме положительных элементов /-й строки матрицы, в противном случае Р) равен произведению отрицательных элементов /-й строки матрицы. Вывести массив Р на экран.
  • 32. Дана целочисленная матрица М х К. Найти минимальное значение для верхней половины матрицы и максимальное значение для нижней половины.
  • 33. Целочисленную матрицу К{8,8} заполнить нулями и единицами, расположив их в шахматном порядке. Дополнительно: сделать то же самое для квадратной матрицы произвольного порядка.

Контрольные вопросы

  • 1. Что такое «матрица»? Приведите примеры.
  • 2. Каким образом элементы матрицы записываются в оперативную память?
  • 3. Данные каких типов могут быть элементами матрицы? Приведите примеры.
  • 4. Назовите атрибуты матрицы. Поясните на примерах.
  • 5. Как объявить двумерный массив в программе? Приведите примеры.
  • 6. Можно ли в программе объявить число строк и число столбцов матрицы как константы? Для чего это делается? Приведите примеры.
  • 7. Можно ли не объявлять размеры матрицы не как константы? Будет ли это считаться ошибкой? Объясните.
  • 8. Можно ли задавать размеры матрицы при каждом запуске программы? Как это сделать? Приведите пример.
  • 9. Что такое «индекс элемента матрицы»? Какие индексы имеют элементы матрицы? Приведите примеры.
  • 10. Как получить доступ к конкретному элементу матрицы? Приведите примеры.
  • 11. Каким образом можно сформировать матрицу? Приведите примеры.
  • 12. Как вывести матрицу на экран? Приведите примеры.
  • 13. Что такое главная диагональ матрицы? Как в программе определить, принадлежит ли элемент матрицы главной диагонали? Приведите примеры.
  • 14. Что такое побочная диагональ матрицы? Как в программе определить, принадлежит ли элемент матрицы побочной диагонали? Приведите примеры.
  • 15. Для каких матриц существуют главная и побочная диагонали? Приведите примеры.
  • 16. Что такое порядок матрицы? Объясните на примере.
  • 17. Для чего в программе можно использовать двумерный массив? Приведите пример.
  • 18. Как вычислить сумму всех элементов матрицы? Приведите пример.
  • 19. Как вычислить произведение всех элементов матрицы? Приведите пример.
  • 20. Как найти среднее арифметическое всех элементов матрицы?
  • 21. Как определить максимальный элемент двумерного массива? Приведите пример.
  • 22. Как определить координаты максимального элемента двумерного массива? Приведите пример.
  • 23. Как найти минимальный элемент двумерного массива? Приведите пример.
  • 24. Как определить координаты минимального элемента двумерного массива? Приведите пример.
  • 25. Как найти все максимальные (минимальные) элементы матрицы? Приведите примеры.
  • 26. Можно ли сформировать одномерный массив из элементов матрицы? Как это сделать? Приведите примеры.
  • 27. Чем формирование одномерного массива по строкам матрицы отличается от формирования одномерного массива по столбцам матрицы? Поясните на примерах.
  • 28. Можно ли сформировать одномерный массив из элементов главной (побочной) диагонали матрицы? Приведите примеры.
 
< Пред   СОДЕРЖАНИЕ     След >