Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по основам алгоритмизации и программи....doc
Скачиваний:
41
Добавлен:
02.11.2018
Размер:
2.69 Mб
Скачать

Многомерные массивы (матрицы)

В языке С(C++) определены только одномерные массивы, но поскольку элементом массива может быть массив, можно определить и многомерные массивы. Многомерный массив – это массив элементами которого являются массивы. Размерность массива – это количество индексов, используемых для доступа к конкретному элементу массива. Пример объявления двухмерного массива:

int mas[5][15];

Константное выражение, определяющее одну из размерностей массива, не может принимать нулевое значение:

int mas[0][7]; // ошибка

Можно инициализировать и многомерные массивы. Инициализация выполняется построчно, то есть в порядке возрастания самого правого индекса. Именно в таком порядке элементы многомерных массивов располагаются в памяти компьютера, например:

int mas[2][3]={2, 14, 36, 23, 1, 9};

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

2 14 36

23 1 9

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

int mas[][3]={ 34, 23, 67,

38, 56, 73,

37, 94, 28 };

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

int mas[][3]={{ 0 },

{ 10, 11},

{ 21, 21, 22} };

Если в какой-то группе {…} отсутствует значение, то соответствующему элементу присваивается 0. Предыдущий оператор будет эквивалентен следующему определению:

int mas[][3]={{ 0, 0, 0 },

{ 10, 11, 0 },

{ 21, 21, 22} };

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

n= mas[i][j]; // работа с элементом расположенным на i-ой

mas[i][j]=n; // строке и в j-ом столбце матрицы mas

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

int s[2][3];

Если при обращении к некоторой функции написать s[0], то будет передаваться нулевая строка массива s.

int b[2][3][4];

При обращении к массиву b можно написать, например, b[1][2] и будет передаваться вектор из четырех элементов, а обращение b[1] даст двухмерный массив размером 3 на 4. Нельзя написать b[2][4], подразумевая, что передаваться будет вектор, потому что это не соответствует ограничению наложенному на использование сечений массива.

Примеры программ

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

Пример . Транспонировать матрицу относительно главной диагонали.

#include <stdio.h>

#define nn 3

void main()

{ int mas[nn][nn],i,j,kk;

printf("\n‚Введите матрицу");

for(i=0;i<nn;i++) // цикл по строкам матрицы

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

{ printf("\n‚введите элемент mas[%d][%d] = ",i,j);

scanf("%d",&mas[i][j]);

}

clrscr();

printf("\nИсходная матрица "); // Вывод матрицы на экран

for(i=0;i<nn;i++) // цикл по строкам матрицы

{ printf("\n");

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

printf("%5d",mas[i][j]);

}

// пример транспонирования используя оператор for

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

for(j=i+1;j<nn;j++)

{ kk=mas[i][j];

mas[i][j]=mas[j][i];

mas[j][i]=kk;

}

// пример транспонирования используя оператор do while

i=0;

do

{ j=i+1;

do

{ kk=mas[i][j];

mas[i][j]=mas[j][i];

mas[j][i]=kk;

} while(++j<nn);

} while(+i<nn);

// пример транспонирования используя оператор while

i=0;

while(i<nn)

{ j=i+1;

while(j<nn)

{ kk=mas[i][j];

mas[i][j]=mas[j][i];

mas[j++][i++]=kk;

}

}

printf("\nИсходная матрица "); // Вывод матрицы на экран

for(i=0;i<nn;i++) // цикл по строкам матрицы

{ printf("\n");

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

printf("%5d",mas[i][j]);

}

}

Пример . Разработать программу выявления седловой точки в матрице размерности п х п. Седловой точкой в матрице называют элемент, одновременно наибольший в своей строке и наименьший в своем столбце.

#include<stdio.h>

#define n 4

void main()

{ int ms[n][n],i,i1,i2,j,j1,k,kk;

clrscr();

printf("\n‚Введите матрицу");

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

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

{ printf("\ms[%2d][%2d]= ",i,j);

scanf("%d",&ms[i][j]);

}

clrscr();

printf("\nВведенный массив MS");

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

{ printf("\n");

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

printf("%3d",ms[i][j]);

}

// блок поиска седловой точки

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

{ k=ms[i][0]; i1=0; j1=0; // начальное значение координат в матрице

// для поиска седловой точки

for(j=0;j<n;j++) // цикл анализа i-ой строки

if (ms[i][j]>k) // найдено новое максимальное в строке

{ k=ms[i][j]; // запоминаем найденное значение

i1=i; j1=j; // и его координаты в матрице

}

kk=0;

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

if(ms[i1][j1]>=ms[i2][j1] && i1!=i2) kk=1;

if(kk==0)

printf("\nседловая точка = %d \nкоординаты : MS[%d][%d] ",

ms[i1][j1],i1,j1);

}

}

Пример . Разработать программу умножения двух целочисленных матриц чисел.

#include<stdio.h>

void main()

{ int i,j,k,n,t;

int a[3][4],b[4][2],c[3][2];

printf("\nВведите матрицу a");

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

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

{ printf("\na[%d][%d]=",i,j);

scanf("%3d",&a[i][j]);

}

printf("\n Введите матрицу b");

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

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

{ printf("\nb[%d][%d]=",i,j);

scanf("%3d",&b[i][j]);

}

// умножение матриц используя оператор while

i=0;

while(i<3)

{ j=0;

while(j<2)

{ c[i][j]=0;

k=0;

while(k<4)

{ c[i][j]+=a[i][k]*b[k][j];

k++;

}

j++;

}

i++;

}

// умножение матриц используя оператор do while

i=0;

do

{ j=0;

do

{ c[i][j] = 0;

k = 0;

do

{ c[i][j] += a[i][k] * b[k][j];

k++;

} while( k < 3 );

j++;

} while( j < 3);

i++;

} while( i < 3);

puts("\nРезультирующая матрица c");

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

{ printf("\n");

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

printf("%3d",c[i][j]);

}

}

Пример . Построить спираль Улама в квадрате из N  N клеток. В клетку в центре ставится 1, затем справа от единицы ставится 2, ниже – 3 и т.д., по ходу часовой стрелки ставятся последовательные числа натурального ряда. Результирующая матрица выводится на экран, при этом все простые числа заменяются звездочкой '*'.

#include<stdio.h>

#include<conio.h>

#define n 5

int main()

{

int i,i1,i2,j,j1,j2,

k=0, // направление движения

s=1; // значение заносимое в матрицу

static int mt[n][n];

i1=i2=j1=j2=n/2; // координаты середины матрицы

mt[i1][j1]=1; // 1 ставится в центр матрицы

while(s<n*n)

{ switch(k)

{ case 0: // движение вправо

if(j2<n-1) j2++; // изменение правой границы

for(j=j1+1; j<=j2; j++)

if(mt[i1][j]==0) mt[i1][j]=++s;

k=1; // изменение направления движения вниз

break;

case 1: // движение вниз

if(i2<n-1) i2++; // изменение нижней границы

for(i=i1+1; i<=i2; i++)

if(mt[i][j2]==0) mt[i][j2]=++s;

k=2; // изменение направления движения влево

break;

case 2: // движение влево

if(j1>0) j1--; // изменение левой границы

for(j=j2-1; j>=j1; j--)

if(mt[i2][j]==0) mt[i2][j]=++s;

k=3; // изменение направления движения вверх

break;

case 3: // движение вверх

if(i1>0) i1--; // изменение верхней границы

for(i=i2-1; i>=i1; i--)

if(mt[i][j1]==0) mt[i][j1]=++s;

k=0; // изменение направления движения вправо

break;

}

}

clrscr();

puts("spiral Ylama");

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

{ printf("\n");

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

{ k=0;

for(s=2; s<mt[i][j]-1;s++) // цикл проверки является ли mt[i][j]

if(mt[i][j] % s==0) // простым числом

{ k=1;

break;

}

if(k==0 && mt[i][j]!=1) printf("%s"," * ");

else printf("%3d",mt[i][j]);

}

}

return 0;

}