Садржај
3 Променљиве, подаци, типови
3.5 Текстуални подаци (стрингови, ниске)
4 Гранања
4.7 Гранања - разни задаци
5 Петље
5.1 Врсте петљи
5.2 Наредбе break и continue
6 Статички методи
6.4 Корист од метода
7 Низови
7.2 Низови - вежбање
8 Матрице
9 Кориснички дефинисани типови
10 Фајлови

Употреба матрица

У приручнику Увод у програмирање у програмском језику C# прочитајте поглавља 8.1 и 8.2 (стране 226-247).


Поновимо укратко најважније из наведеног поглавља приручника. Декларација матрице је врло слична декларацији низа. На пример, делкарацију матрице целих бројева пишемо овако:

int[ , ] a;

Једина разлика у односу на декларацију низа је зарез (запета) између угластих заграда. Овом декларацијом смо најавили да ће име a представљати матрицу, када за ту матрицу буде заузета (алоцирана) меморија. Простор у меморији за елементе матрице можемо да резервишемо, на пример, овако:

a = new int[v, k];

где су v, k целобројне променљиве са позитивним вредностима. Наведеном декларацијом је резервисан простор за укупно \(v \cdot k\) елемената, распоређених у \(v\) врста и \(k\) колона. Заузета меморија се не може ефикасно проширивати, тј. није могуће на ефикасан начин матрици додати врсту или колону. Могуће је једино поново алоцирати простор, који може да буде већи од претходно алоцираног (као и код низова). У случају да нам је потребна матрица која ће бити проширивана, боље је користити листу листи (ово ћемо показати на примеру нешто касније).

Иницијализација матрице

Ако су елементи матрице унапред познати, матрицу можемо да задамо овако:

int[,] a = {
    { 11, 12, 13, 14 },
    { 21, 22, 23, 24 },
    { 31, 32, 33, 34 }
};

На овај начин формирана је матрица од 3 врсте и 4 колоне.

Димензије и исписивање матрице

Број врста матрице a се добија као a.GetLength(0), а број колона као a.GetLength(1). Укупан број елемената матрице a можемо да добијемо било као a.Length или као a.GetLength(0) * a.GetLength(1).

Приликом исписивања матрице обично желимо да сваку врсту матрице прикажемо у посебном реду стандардног излаза. Да бисмо то постигли, елементе сваког реда матрице приказујемо у (унутрашњој) петљи помоћу метода Console.Write, а након те петље пишемо Console.WriteLine(); - по исписивању врсте матрице прелазимо у нови ред.

for (int red = 0; red < a.GetLength(0); red++)
{
    for (int kol = 0; kol < a.GetLength(1); kol++)
    {
        Console.Write("{0} ", a[red, kol]);
    }
    Console.WriteLine();
}

Пример - Најбољи ученик и најтежи предмет

Дата је матрица закључних оцена у којој, као и у школском дневнику, врсте (редови) одговарају ученицима, а колоне предметима.

Написати програм који најпре у једном реду учитава број врста (тј. број ученика) \(v\) и број колона (тј. број предмета) \(k\), затим у сваком од наредних \(v\) редова учитава закључне оцене једног ученика раздвојене по једним размаком, а на основу тих података исписује редни број (првог) најуспешнијег ученика и редни број (првог) најтежег предмета, бројећи од 0.

Најуспешнији ученик је онај коме је просечна оцена највећа, а самим тим је и збир оцена највећи. Најтежи предмет је онај из кога је просечна оцена најмања. Закључујемо да је, након што се учитају подаци, потребно одредити

  • редни број врсте (реда) са највећим збиром

  • редни број колоне са најмањим збиром

Кроз овај пример смо се подсетили да више података датих у једном реду стандардног улаза учитавамо тако што га најпре смештамо у низ стрингова наредбом s = Console.ReadLine().Split(). Број учитаваних података може бити познат и пре писања програма (као када учитавамо димензије матрице - то су два броја) и у том случају следећим наредбама те податке претварамо у целобројне вредности и смештамо у појединачне променљиве (v и k). Када у једном реду имамо податке чији је број велики, или није ни познат у време писања програма, онда те податке најчешће пребацујемо у низ или у један ред, или једну колону матрице помоћу петље (у овом примеру користили смо један ред матрице).

Да бисмо израчунали збир елемената сваке врсте, користимо двоструку петљу (време рачунања је сразмерно броју елемената матрице). На крају програма, у још једној двострукој петљи рачунамо збир елемената сваке колоне. Обратите пажњу на редослед петљи при рачунањима ових збирова.

Листа листи као матрица

Претпоставимо да у претходном примеру нису познате димензије матрице (број ученика и број предмета), а да се врсте матрице учитавају до краја улазних података. У том случају уместо матрице може да се употреби листа листи целих бројева. Почетак функције Main би изгледао овако

List<List<int> > ocene = new List<List<int>>();
string tekst = Console.ReadLine();
int v = 0, k = 0;
while (tekst != null)
{
    string[] s = tekst.Split();
    k = s.Length;
    ocene.Add(new List<int>()); // nova vrsta
    for (int j = 0; j < s.Length; j++)
        ocene[v].Add(int.Parse(s[j])); // novi broj u vrsti
    v++;
    tekst = Console.ReadLine();
}

док је наставак исти као у примеру горе, осим што уместо ocene[i, j] сада треба писати ocene[i][j].

Приликом тестирања ове верзије програма, након уношења последње врсте матрице треба откуцати Ctrl+Z и Enter (на оперативним системима Windows), односно Ctrl+D и Enter (на оперативним системима Unix/Linux). Тиме се затвара улазни ток података са тастатуре и саопштава се програму да нема више података.

Матрице и референце

Матрице су, као и низови и стрингови (ниске), референцирани тип података. Због тога све што је речено за низове као параметре или повратне вредности метода, важи и за матрице. На пример, ако у програму користимо више матрица, можемо да напишемо методе за учитавање и исписивање матрице и на тај начин избегнемо понављање сличних делова кода.

Пример - Бабе и деде

Релација на датом коначном скупу може да се зада бинарном квадратном матрицом (матрица је бинарна ако је сваки њен елемент једнак 0 или 1, а квадратна ако има исти број врста и колона). При томе јединица у реду i и колони j означава да је i-ти елемент у релацији са j-тим. На пример, ако је релација ~ на скупу {A, B, C} задата матрицом

1 1 0
0 0 1
1 0 0

онда важи A~A, A~B, B~C, C~A, а остали парови елемената нису у релацији.


Бинарним квадратним матрицама задате су релације M и T димензије N x N, са значењем „бити мајка” и „бити отац”. На пример, \(M_{i,j} = 1\) значи да је особа i мајка особе j.

Написати програм који учитава матрице M и T а затим израчунава и приказује матрице B и D са значењем „бити баба” и „бити деда”.

Особа x је баба особе z ако и само ако постоји особа y, таква да је x мајка особе y, а y је било мајка, било отац особе z. Слично томе, особа x је деда особе z ако и само ако постоји особа y, таква да је x отац особе y, а y је било мајка, било отац особе z.

На основу ових увида можемо да напишемо следећи програм:

Тродимензиони и вишедимензиони низови

У уводном тексту поглавља о матрицама, матрице смо назвали дводимензионим низовима. Напоменимо сада да број димензија низа није ограничен на 1 или 2 (мада нам ретко могу затребати низови са више од две димензије). На пример, могуће је задати следећи тродимензиони низ:

int[,,] a =
  {
      {
          { 111, 112, 113, 114},
          { 121, 122, 123, 124},
          { 131, 132, 133, 134}
      },
      {
          { 211, 212, 213, 214},
          { 221, 222, 223, 224},
          { 231, 232, 233, 234}
      }
  };

После овакве дефиниције тродимензионог низа a, наредбе

Console.WriteLine(a.GetLength(0));
Console.WriteLine(a.GetLength(1));
Console.WriteLine(a.GetLength(2));

исписују редом бројеве 2, 3, 4, јер постоје две могуће вредности за први индекс (0 и 1), три за други (0, 1 и 2) и четири за трећи (0, 1, 2 и 3). Према томе, у „низу” a постоје следећи елементи

a[0,0,0]  a[0,0,1]  a[0,0,2]  a[0,0,3]
a[0,1,0]  a[0,1,1]  a[0,1,2]  a[0,1,3]
a[0,2,0]  a[0,2,1]  a[0,2,2]  a[0,2,3]

a[1,0,0]  a[1,0,1]  a[1,0,2]  a[1,0,3]
a[1,1,0]  a[1,1,1]  a[1,1,2]  a[1,1,3]
a[1,2,0]  a[1,2,1]  a[1,2,2]  a[1,2,3]

тако да је нпр. вредност a[1, 0, 2] једнака 213.

(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+