Thursday, March 19, 2020

Nizovi u C# programskom jeziku


Već ste učili kako se deklarišu i prave promenjive i konstante i kako da iste mogu da budu različitih tipova podataka. Ukoliko se ne sećate baš najbolje te teme, možete se podsetiti na ovom postu. Znači promenjive i konstante su odlične kada imate potrebu za manje podataka, ali šta da radite ako vam na primer treba 1000 promenjivih ili čak da vi ne znate koliko će vam tačno biti potrebno promenjivih? Nećete valjda deklarisati 1000 promenjivih, na šta bi taj vaš kod ličio? Zbog takvih situacija u C# programskom jeziku ali definitivno i u svim drugim programskim jezicima postoji nešto što zovemo nizovi. U informatičkoj literaturi piše da je Array – niz fiksan broj promenjivih koje zovemo elementi. To bi se tako moglo reći samo kad je niz definisan određenim brojem elemenata. Ako mene pitate, najjednostavnije rečeno, niz vam je indeksiran skup podataka istog tipa. Sintakse nizova u C# programskom jeziku su sledeće:

Jednodimenzionalan niz:
tip [] naziv_niza;

Dvodimenzionalni niz:
tip [ , ] naziv_niza;

Višedimenzionalan niz:
tip [ , , … ] naziv_niza;

Ortogonalni niz:
tip [ ] [ ] naziv_niza:
     

Nizovi nisu ograničeni samo na osnovne tipove podataka nego se mogu deklarisati i kao klase, strukture, numeracije ili neki tip podataka kojeg ste sami napravili. Broj elemenata koji može biti u nizu zavisi od vašeg procesora ali i operativnog sistema. Negde oko 4 biliona, ali imajte u vidu da Linux operativni sistem to više ograničava nego Windows 10 operativni sistem. Moj savet vam je da nikad ne pravite tako velike nizove gde se to može izbeći. Bolje napraviti više nizova.  


( Nizovi u C# programskom jeziku prikazani mapom uma )

Ukoliko ste vi neko ko poznaje C++ programski jezik, treba da imate na umu da i pored iste svrhe nizovi u C# programskom jeziku nisu isto što i nizovi u C++ programskom jeziku, niti je njihova deklaracija ista. Ukoliko vas interesuje na koji način funkcionišu nizovi u C++ programskom jeziku pogledajte ovde. Vi što ste nekada učili Visual Basic programski jezik, sećate se da je niz predstavljao promenjiva tipa SAFEARRAY, što znači da je rad sa nizom podrazumevalo izvesno angažovanje sistema, ali je olakšavao rad sa nizovima. I ono je bolje nego što su to nizovi u CC++  programskim jezicima. Jednostavno, C# programski jezik je prevazišao neke nedostatke koje nizovi imaju i sada nizove tretira kao svaki objekat sa vlastitim metodama i svojstvima što vama olakšava rad sa nizovima. C# programski jezik podržava čak nizove u formi izričitog različitog tipa. Niz u C# programskom jeziku je sam po sebi referentni tip, čak i kad su njegovi elementi vrednosti tipovi. To znači da promenjiva niza ukazuje na neprekidan blok memorije koji sadrži elemente niza u hip memoriji kao što je to slučaj sa klasama. Međutim da sada ne bismo vas plašili i otišli previše daleko pogledajte praktičan primer kako se lako koriste nizovi.

Jednodimenzionalni nizovi


Jednodimenzionalni nizovi su nešto što ćete često koristiti kod jednostavniji zadataka. Međutim kod ozbiljnijih i komplikovaniji zadataka ćete u budućnosti koristiti Generičke liste, koje ćete učiti kasnije. Pogledajmo prvo kako se deklariše i inicijalizuje jednodimenzionalan niz od 5 elemenata:

int[] array = new int[5];

array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
array[4] = 5;

Kao što vidite u C# programskom jeziku niz se prepoznaje po uglastim zagradama iza tipa elementa jer predstavljaju indeks niza koji omogućava pristupanje određenom elementu niza na osnovu njegove pozicije u nizu. Obratite pažnju da indeks niza uvek počinje od 0. Ako ne znate koliko će vaš jednodimenzionalan niz imati elemenata, onda ga možete deklarisati i ovako:

int[] array;

Takođe možete i na lakši način da deklarišete i inicijalizujete niz; najčešće će te to u praksi raditi ovako:

int[] array = {0123456789};

Pokrenite Visual Studio Code i nazovite vaš program onedimensionalarray. Ukucajte sledeći kod u proceduri Main:

byte NumberOfCities = 0;
bool correct = false;
string[] cities;

do
{
   Write("How many cities you want to enter into the system? ");
   correct = byte.TryParse(ReadLine(), out NumberOfCities);
   WriteLine();
              
while (!correct);

U navedenom kodu mi hoćemo da korisnik sam odluči koliko gradova želi da unese u neki naš zamišljeni sistem. Znači mi treba da pitamo korisnika koliko gradova hoće da unese i da na osnovu tog podatka deklarišemo niz za određen broj elemenata. Mogli smo ovde da izostavimo to pitanje i da koristimo niz za koji ne znamo koliko će imati elemenata. To bi onda značilo neracionalno korišćenje memorije i komplikovanja koda bespotrebno. Uvek se trudite da odredite tačan broj elemenata ako to zadatak dozvoljava.

cities = new string[NumberOfCities];
for (int i = 0i < NumberOfCitiesi++)
{
    Write($"Enter {i + 1} of {NumberOfCities} cities: ");
    cities[i] = ReadLine();

}

Promenjiva NumberOfCities uzima podatak od korisnika i mi taj podatak koristimo i za deklarisanje niza ali i za petlju for koja sa lakoćom prelazi kroz sve elemente niza i unosi grad koji je korisnik naveo da unosi u sistem. Pogledajte ostatak koda:

Array.Sort(cities);

WriteLine();
foreach (var item in cities)
{
    WriteLine(item);

}

WriteLine();

S obzirom da su nizovi objekti u C# programskom jeziku, oni već sadrže veoma korisna svojstva i metode poput sortiranja, kopiranja, kloniranja itd.; koje sa lakoćom možete koristiti u vašim programima bez potrebe da vi morate sve to od nule iskodirati i ponovo vratiti u niz. Zato u navedenom kodu mi sortiramo naš niz samo jednom linijom koda. Nadam se da ćete umeti da cenite sav taj odrađeni posao za vas. I na kraju, ukoliko ne menjate podatke u jednodimenzionalnom nizu, nego ih samo čitate i prikazujete na terminalu, najbolje je da koristite petlju foreach. Zašto? Pročitajte ovde. Pogledajte kod celog programa:

using System;
using static System.Console;

namespace onedimensionalarray
{
    class Program
    {
        static void Main(string[] args)
        {
            byte NumberOfCities = 0;
            bool correct = false;
            string[] cities;

            do
            {
                Write("How many cities you want to enter into the system? ");
                correct = byte.TryParse(ReadLine(), out NumberOfCities);
                WriteLine();
                
            } while (!correct);

            cities = new string[NumberOfCities];

            for (int i = 0i < NumberOfCitiesi++)
            {
                Write($"Enter {i + 1} of {NumberOfCities} cities: ");
                cities[i] = ReadLine();

            }

            Array.Sort(cities);

            WriteLine();

            foreach (var item in cities)
            {
                WriteLine(item);

            }

            WriteLine();
            
        }
    }
}

Kad pokrenete navedeni program u zavisnosti od vašeg unosa podataka, rezultat će biti sličan sledećem:

How many cities you want to enter into the system? 5

Enter 1 of 5 cities: Belgrade
Enter 2 of 5 cities: Berlin
Enter 3 of 5 cities: Washington
Enter 4 of 5 cities: New York
Enter 5 of 5 cities: Moscow

Belgrade
Berlin
Moscow
New York
Washington

Kako to sve izgleda možete pogledati i na video-u:


( C# & .NET Core - 15. One - Dimensional Array )

Dvodimenzionalni nizovi

Za dvodimenzionalne nizove možemo reći da će vam oni zaista koristiti. Za razliku od jednodimenzionalni nizova koji imaju jedan indeks, dvodimenzionalni nizovi imaju dva, trodimenzionalni tri itd. Postavlja se samo pitanje koliko je nešto komplikovano u stvarnom životu što hoćete da pojednostavite pravilnim izborom nizova u kodu. Pretpostavimo da trebate nekom detetu na brzinu da ispišete tablicu množenja od 1 do 100. To jednostavno možete da uradite sa jednim dvodimenzionalnim nizom. Program nazovite twodimensionalarray i unesite sledeći kod:

using System;
using static System.Console;

namespace twodimensionalarray
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] multipletable = new int[10,10];

            for (int i = 0i < 10i++)
            {
                for (int j = 0j < 10j++)
                {
                    multipletable[i,j] = (i + 1) * (j + 1);
                }
                                
            }

            WriteLine();

            for (int i = 0i < 10i++)
            {
                for (int j = 0j < 10j++)
                {
                    Write(multipletable[i,j] + "\t");

                }
                
                WriteLine();
            }

            WriteLine();

        }
    }
}

Deklarisali smo samo jedan dvodimenzionalni niz sa prvim indeksom od 10 elemenata i isto tako sa drugim indeksom i dobili 100 elemenata. Petljom for u petlji for prođete kroz sve elemente i množite prvi indeks sa drugim. Za ispis ovog dvodimenzionalnog niza ne koristimo petlju foreach jer bi nam u ovom slučaju zakomplikovala kod. Znači za višedimenzionalne nizove petlje for u petljama for su vam idealno rešenje. Kad pokrenete program dobićete sledeći rezultat:

1       2       3       4       5       6          7        8        9       10     
2       4       6       8       10      12      14      16      18      20
3       6       9       12     15      18      21      24      27      30
4       8       12     16     20      24      28      32      36      40
5       10     15     20     25      30      35      40      45      50
6       12     18     24     30      36      42      48      54      60
7       14     21     28     35      42      49      56      63      70
8       16     24     32     40      48      56      64      72      80
9       18     27     36     45      54      63      72      81      90
10     20     30     40     50      60      70      80      90      100

Kako to sve izgleda možete pogledati i na video-u:


( C# & .NET Core - 16. Two - Dimensional Array ( Multiplication Table 1 - 100 ) )

Multidimenzionalni nizovi

Multidimenzionalni nizovi mogu biti veoma komplikovani nizovi i rad sa njima može biti nešto za nijansu teže raditi, ali kod ovih nizova se više treba obratiti pažnju na količinu memorije koju koriste. Takođe morate paziti da se ne zapetljate, posebno što u radu sa multidimenzionalni nizovi koriste i veći broj petlji kako bi se moglo pristupiti svim elementima. Znači, koristite ove nizove jedino ako su oni jedino rešenje. Nazovite sledeći program multidimensionalarray i unesite sledeći kod.

using System;
using static System.Console;

namespace multidimensionalarray
{
    class Program
    {
        static void Main(string[] args)
        {
            // declare two three-dimensional arrays

            byte[,,] a = new byte[3,3,3] {
                   { {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} }
            };

            byte[,,] b = new byte[3,2,4] {
                   { {1,2,3,4}, {5,6,7,8} },
                   { {9,10,11,12}, {13,14,15,16}, },
                   { {17,18,19,20}, {21,22,23,24}, }
            };
            
            // characteristics of array a

            WriteLine();
            WriteLine("Three-dimensional array a.");
            WriteLine("Lenght: " + a.Length);
            WriteLine("GetLenght(0): " + a.GetLength(0));
            WriteLine("GetLenght(1): " + a.GetLength(1));
            WriteLine("GetLenght(2): " + a.GetLength(2));
            WriteLine();
            WriteLine("Rank: " + a.Rank);

            WriteLine();
            WriteLine("Elements:");
            WriteLine();

            for (int i = 0i < 3i++)
            {
                for (int j = 0j < 3j++)
                {
                    for (int k = 0k < 3k++)
                    {
                        Write(a[i,j,k] + "\t");

                    }

                    WriteLine();
                    
                }

                WriteLine();

            }

            WriteLine();

            // characteristics of array b

            WriteLine();
            WriteLine("Three-dimensional array b.");
            WriteLine("Lenght: " + b.Length);
            WriteLine("GetLenght(0): " + b.GetLength(0));
            WriteLine("GetLenght(1): " + b.GetLength(1));
            WriteLine("GetLenght(2): " + b.GetLength(2));
            WriteLine();
            WriteLine("Rank: " + b.Rank);

            WriteLine();
            WriteLine("Elements:");
            WriteLine();

            for (int i = 0i < 3i++)
            {
                for (int j = 0j < 2j++)
                {
                    for (int k = 0k < 4k++)
                    {
                        Write(b[i,j,k] + "\t");

                    }

                    WriteLine();
                    
                }

                WriteLine();

            }

            WriteLine();

        }
    }
}

U ovom programu smo kreirali dva jednostavna trodimenzionalna niza različitih dužina indeksa, tek toliko da bi ste videli kako ti nizovi izgledaju i kako im se dodeljuju neke najprostije vrednosti. Obratite pažnju na ugnježdene petlje koje moraju da se koriste da bi prešle preko svih elemenata niza. Kad pokrenete program dobićete sledeći rezultat:

Three-dimensional array a.
Lenght: 27
GetLenght(0): 3
GetLenght(1): 3
GetLenght(2): 3

Rank: 3

Elements:

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



Three-dimensional array b.
Lenght: 24
GetLenght(0): 3
GetLenght(1): 2
GetLenght(2): 4

Rank: 3

Elements:

1       2       3       4
5       6       7       8

9       10      11      12
13      14      15      16

17      18      19      20
21      22      23      24   


Kako to sve izgleda možete pogledati i na video-u:


( C# & .NET Core - 17. Multi - Dimensional Array )

Ortogonalni nizovi

Kod nas u Srbiji ako bi ste nekom kazali ortogonalni ili zupčasti nizovi, mali broj ljudi bi vas razumelo o čemu pričate. Mi jednostavno volimo u tehnologijama da koristimo engleske reči. Zato ako kažete jagged nizovi, to će mnogima biti razumljivije. Ono što je karakteristično za njih jeste jednostavno da su to nizovi u nizovima. Možete se pitati kome bi trebalo toliko petljanje i komplikovanje da se koristi ova vrsta niza. Što se mene tiče ja ovakve nizove zaobilazim, međutim ako kažete Rubikova kocka, onda je jagged niz idealan za nju. Rubikova kocka ima 6 površina sa 3 x 3 polja, što čini ukupno 54 elementa. Nazovite sledeći program jaggedarray i unesite sledeći kod:

using System;
using static System.Console;

namespace jaggedarray
{
    class Program
    {
        static void Main(string[] args)
        {
            // the rubikscube with all colors on the correct place

            byte[][] rubikscube = new byte[6][];

            rubikscube[0] = new byte[9] {1,1,11,1,11,1,1};
            rubikscube[1] = new byte[9] {2,2,22,2,22,2,2};
            rubikscube[2] = new byte[9] {3,3,33,3,33,3,3};
            rubikscube[3] = new byte[9] {4,4,44,4,44,4,4};
            rubikscube[4] = new byte[9] {5,5,55,5,55,5,5};
            rubikscube[5] = new byte[9] {6,6,66,6,66,6,6};

            // move the rubikscube - one move down - third row vertically

            rubikscube[0][2] = 4;
            rubikscube[0][5] = 4;
            rubikscube[0][8] = 4;

            // because we change this and other fields of the rubikscube are changed

            rubikscube[1][2] = 1;
            rubikscube[1][5] = 1;
            rubikscube[1][8] = 1;

            rubikscube[2][2] = 2;
            rubikscube[2][5] = 2;
            rubikscube[2][8] = 2;

            rubikscube[3][2] = 3;
            rubikscube[3][5] = 3;
            rubikscube[3][8] = 3;

            WriteLine();

            // show all rubikscube's fields with changes

            for (int i = 0i < rubikscube.Lengthi++)
            { 
                for (int j = 0j < rubikscube[i].Lengthj++)
                {
                    Write(rubikscube[i][j] + "\t");

                }

                WriteLine();

            }

            WriteLine();
                         
        }         
    }
}

Kao što možete videti u prethodnom kodu, Rubikovu kocku predstavljamo jagged nizom tako što imamo jedan niz od 6 elemenata koji sadrži 6 jednodimenzionalnih nizova od 9 elemenata. Elementi u nizu se predstavljaju od 0 do 5 i zato i mi tako predstavljamo šest površina kocke. Međutim, vrednosti elemenata predstavljamo od 1 do 6. Svaki broj u elementu je jedna boja. Tokom proračuna i rada sa kockom najbolje da to uvek budu brojevi; ali kad bi ste recimo crtali kocku na nekoj formi onda bi ste koristili i neku enumeraciju sa svih 6 boja i samo kod prikazivanja kocke bi ste krajnji rezultat prikazivali u pravim bojama. Ovde prvo imamo samo jedan jagged niz i samo one koje trebamo elemente da promenimo kod bilo kojeg poteza to i menjamo. Ali isto tako moramo da promenimo i druge elemente kocke koji su izazvani pomeranjem bilo kojeg niza. U ovom programu okrenuli smo treći red vertikalno na dole i to je izazvalo promene. Kad pokrenete program dobićete rezultat promena u nizu. Uzmite pravu Rubikovu kocku i videćete da je ista promena kao u programu.

1       1       4       1       1       4       1       1       4      
2       2       1       2       2       1       2       2       1      
3       3       2       3       3       2       3       3       2      
4       4       3       4       4       3       4       4       3      
5       5       5       5       5       5       5       5       5      
6       6       6       6       6       6       6       6       6     

Kao što možete primetiti leva i desna strana kocke nema nikakvu promenu kao što ni 2, 5 i 8 element se nikada u kocki ne menjaju jer su uvek isti. U ovom primeru promenjen je samo desni treći red za jednu poziciju. Kako to sve izgleda možete pogledati i na video-u:


( C# & .NET Core - 18. Jagged Array )





   






No comments:

Post a Comment