Кратко съдържание



страница54/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   50   51   52   53   54   55   56   57   ...   73

Многомерни масиви


Освен вече разгледаните едномерни масиви, .NET Framework поддържа и многомерни такива (масиви с няколко размерности). Декларирането на многомерен масив е почти същото, както при едномерните, но само с една разлика – трябва да поставим запетая между размерностите му:

int[,] matrix = new int[3,3];

char[,,] box = new char[2,5,10];


Инициализиране и достъп до елементите


Ако искаме да инициализираме многомерен масив още при декларация трябва да спазим следното правило, а именно че трябва да поставим всяко измерение в отделни "къдрави скоби". Ето и пример:

int[,] matrix = { {1, 2, 3} , {4, 5, 6} , {7, 8, 9} };

Достъпът до елементите отново е по индекс, само че в многомерния вари­ант отново трябва да поставим запетая между индексите на отделни­те размерности:

int elem = matrix[3,3];

box[1,2,3] = 'a';


Разположение в паметта


Многомерните масиви разполагат елементите си последователно – един след друг в линейни блокове от динамичната памет. Ето как би изглеж­дало това за вече декларирания и инициализиран с естествените числа от 1 до 9 двумерен масив matrix:


Многомерни масиви – пример


В следващия пример ще използваме двумерни масиви за да реализираме умножение на матрици:

using System;
class MatrixMultiplicationDemo

{

static void PrintMatrix(int[,] aMatrix)



{

for (int row = 0; row < aMatrix.GetLength(0); row++)

{

for (int col = 0; col < aMatrix.GetLength(1); col++)



{

Console.Write("{0} ", aMatrix[row, col]);

}

Console.WriteLine();



}

Console.WriteLine();

}
static int[,] Mult(int[,] aMatrix1, int[,] aMatrix2)

{

int width1 = aMatrix1.GetLength(1);



int height1 = aMatrix1.GetLength(0);

int width2 = aMatrix2.GetLength(1);

int height2 = aMatrix2.GetLength(0);
if (width1 != height2)

{

throw new ArgumentException("Invalid dimensions!");



}
int[,] resultMatrix = new int[height1, width2];

for (int row = 0; row < height1; row++)

{

for (int col = 0; col < width2; col++)



{

resultMatrix[row, col] = 0;

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

{

resultMatrix[row, col] +=



aMatrix1[row, i] * aMatrix2[i, col];

}

}



}
return resultMatrix;

}
static void Main()

{

int[,] m1 = new int[4,2]



{

{1,2},


{3,4},

{5,6},


{7,8}

};

PrintMatrix(m1);


int[,] m2 = new int[2,3]

{

{1,2,3},



{4,5,6}

};

PrintMatrix(m2);


int[,] m3 = Mult(m1, m2);

PrintMatrix(m3);

}

}

Как работи примерът?


Условието, на което трябва да отговарят две матрици за да можем да ги умножим е: броят на стълбовете на първата матрица да е равен на броя на редовете на втората матрица. Ако това не е изпълнено подаваме ArgumentException. След умножението новополучената матрица ще има следните размери: брой редове – броят на редовете на първата матрица, брой стълбове – броят на стълбовете на втората.

Самото умножение става така: всеки ред на първата матрица се умножава с всеки стълб на втората, т. е. първият елемент от реда с първия от стълба, вторият с втория и т. н. Получените произведения сумираме и това е стойността на елемен­та, който ще запишем в новополучената матрица на ред текущия ред от първата матрица и стълб – текущият от втората.

Ето и изхода от примера:


Масиви от масиви


В .NET Framework могат да се използват още и масиви от масиви или т. нар. назъбени (jagged) масиви. Може би се чудите от къде идва това име? След следващите редове ще ви се изясни.

Назъбеният масив представлява масив от масиви, т. е. всеки негов ред на практика е масив, който може да има различна дължина от останалите в назъбения масив, но не може да има различна размерност. Със следващия код декларираме масив от масиви:



int[][] jaggedArray;

Единственото по-особено е, че нямаме само една двойка скоби, както при обикновените масиви, а имаме вече две двойки такива. По следния начин заделяме назъбен масив:

jaggedArray = new int[2][];

jaggedArray[0] = new int[5];

jaggedArray[1] = new int[3];


Възможно е и декларирането, заделянето и инициализацията на един масив от масиви да се извършва в един израз. Ето пример:

int[][] myJaggedArray = {

new int[] {1,3,5,7,9},

new int[] {17,23},

new int[] {0,2,4,6}

};

Инициализиране и достъп до елементите


Достъпът до елементите на масивите, който са част от назъбения, отново е по индекс. Ето пример за достъп до елемента с индекс 3 от масива, който има индекс 0 в по-горе дефинирания назъбен масив jaggedArray:

jaggedArray[0][3] = 12345;

Както споменахме, елементите на назъбения масив може и да са не само едномерни масиви, но и многомерни такива. В следващия код създаваме назъбен масив от двумерни масиви:

int[][,] jaggedOfMulti = new int [3][,] ;

jaggedOfMulti[0] = new int[,] { {9,27}, {10,20} };


Разположение в паметта


Ако все още не ви си е изяснило защо наричаме масивите от масиви – назъбени, може би тази следващата картинка ще ви помогне. На нея може да видим вече дефинирания назъбен масив myJaggedArray и по точно неговото разположение в паметта. Както се вижда, самият назъбен масив съдържа само референции към масивите, а не самите тях. Тъй като не знае каква ще е размерността на всеки от масивите, CLR заделя само референцията за тях. Чак след като се задели памет за някой от масивите елементи на назъбения, тогава се насочва указателя към новосъздадения блок динамична памет.


Триъгълник на Паскал – пример


В следващия пример ще използваме назъбен масив за да генерираме и визуализираме триъгълника на Паскал. Както знаем от математиката, всяко число от триъгълника се образува като се съберат горните две над него. Естествено, това не важи за първото число в триъгълника – 1. Триъгълникът на Паскал има широко приложение в комбинаториката.

using System;
class PascalTriangle

{

static void Main()



{

const int HEIGHT = 12;


// Allocate the array in a triangle form

long [][] triangle = new long[HEIGHT+1][];

for (int row = 0; row <= HEIGHT; row++)

{

triangle[row] = new long[row+1];



}
// Calculate the Pascal's triangle

triangle[0][0] = 1;

for (int row = 0; row < HEIGHT; row++)

{

for (int col = 0; col <= row; col++)



{

triangle[row+1][col] += triangle[row][col];

triangle[row+1][col+1] += triangle[row][col];

}

}


// Print the Pascal's triangle

for (int row = 0; row <= HEIGHT; row++)

{

Console.Write("".PadLeft((HEIGHT-row)*2));



for (int col = 0; col <= row; col++)

{

Console.Write("{0,3} ", triangle[row][col]);



}

Console.WriteLine();



}

}

}



Ето и резултата от изпълнението на програмата:





Сподели с приятели:
1   ...   50   51   52   53   54   55   56   57   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница