Základy programování (IZP) Osmé počítačové cvičení Brno University of Technology, Faculty of Information Technology Božetěchova 1/2, 612 66 Brno - Královo Pole Petr Veigend, iveigend@fit.vutbr.cz 20.11.2017, 10. týden
Důležité informace Můj profil: http://www.fit.vutbr.cz/~iveigend/ Kancelář: A221 Konzultační hodiny: po domluvě emailem Karta Výuka odkaz na osobní stránky Komunikace: email prosím používejte předmět: IZP - <předmět emailu> 2
První projekt výsledky Konzultace: Čtvrtek, odkaz pro zapsání viz mail 3
Náplň cvičení Práce s vektory a maticemi Matematické operace Struktura matice, násobení matic Vyhledávání a řazení Selection sort 4
MATEMATICKÉ OPERACE 5
Násobení vektoru konstantou 6
Součet dvou vektorů 7
Tisk vektoru 8
Vyhledávání a řazení SELECTION SORT (1D POLE) 9
Úvod V rámci této části cvičení budeme implementovat algoritmus Selection Sort Než se do něj pustíme, implementujeme pomocné funkce pro Vyhledání minima v části neseřazeného pole Záměnu dvou prvků (bude se vám hodit v průběhu studia) Začneme ale s implementací jednoduché kostry, která umožní řadit pole libovolné velikosti. 10
Dynamická paměť Program bude přijímat počet prvků v poli jako první argument Je nutné provést kontrolu, zda argument existuje, jinak konec Poté je nutné alokovat paměť pro správné množství prvků (dle prvního argumentu) Funkce malloc, např. 5 prvků int *array = malloc(5*sizeof(int)); Je nutné opět kontrolovat, zda se alokace podařila (array nesmí být po alokaci NULL) Paměť je potřeba uvolnit (příkaz free). Zbytek kódu bude mezi malloc a free. 11
Dynamická paměť Pole je před použitím nutné naplnit hodnotami Pro zjednodušení: generátor náhodných čísel Hlavičkové soubory stdlib.h a time.h Budeme chtít generovat čísla v rozsahu 1 499 Příklad použití generátoru #include<stdlib.h> #include<time.h> srand(time(null)); // inicializace, pouze 1x int cislo = rand() % 20; // rozsah 1-19 Do každého prvku prázdného pole uložte náhodné číslo 12
Vyhledávání minima v části neseřazeného pole Následující funkce bude implementovat vyhledání minima v části neseřazeného pole Hlavička int searchmin(int arrray[], int l, int r); Funkce vrací index minima l je index, od kterého vyhledáváme r je index, po který vyhledáváme 13
Záměna dvou prvků Funkce pro výměnu dvou prvků v poli mezi sebou (swap) Hlavička void exchange (int *i, int *j); 14
Algoritmus Selection Sort 1) Pole je rozděleno na seřazenou část a neseřazenou část 2) V neseřazené části se nalezne minimum a vymění se s prvkem bezprostředně následujícím za seřazenou částí a tento prvek se do ní zahrne 3) Na začátku má seřazená část délku nula, na konci má délku pole 15
Algoritmus Selection sort příklad Neseřazená část Seřazená část Nejmenší prvek 6 60 42 200 4 3 3 60 42 200 4 6 3 4 42 200 60 6 3 4 6 200 60 42 3 4 6 42 60 200 3 4 6 42 60 200 3 4 6 42 60 200 16
Algoritmus Selection Sort Hlavička void selectionsort (int array[], int size); array je pole, které chceme seřadit size je počet prvků pole Budeme používat implementované funkce: searchmin pro vyhledání indexu minima xchg pro výměnu dvou prvků 17
MATICE (2D POLE) 18
2D pole 2D pole si můžeme obecně představit jako matici [řádek,sloupec] [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] [2,1] [2,2] [2,3] [3,0] [3,1] [3,2] [3,3] Pro jednoduchost nejsou uvedeny hodnoty, pouze indexy 19
Práce s 2D poli S dvourozměrným polem budeme pracovat podobně jako s jednorozměrným převedeme 2D na 1D: [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] [2,1] [2,2] [2,3] [3,0] [3,1] [3,2] [3,3] 0 1 2 3 4 5 6 7 8 [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] 20
Práce s 2D poli Datový typ (pro položky typu double) 0 1 2 3 4 5 6 7 8 [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] Datový typ typedef struct { int rows; // počet řádků int cols; // počet sloupců double* data; // položky }array2d_t; 21
Práce s 2D poli Jak byste přistoupili k prvku, který leží na druhém řádku ve třetím sloupci? [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] [2,1] [2,2] [2,3] [3,0] [3,1] [3,2] [3,3] 0 1 2 3 4 5 6 7 8 [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] 22
Práce s 2D poli Jak byste přistoupili k prvku, který leží na druhém řádku ve třetím sloupci? [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] [2,1] [2,2] [2,3] [3,0] [3,1] [3,2] [3,3] 0 1 2 3 4 5 6 7 8 [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] index_řádku * počet_sloupců + index_sloupce 1 * 4 + 2 = 6 23
Příklad: Alokace (2D) pole Pro alokaci se používá rodina funkcí (m/c/re)alloc Hlavičkový soubor stdlib.h Hlavička funkce double *alloc2d(int rows, int cols, array2d_t *arr); Příklad alokace pole 5 čísel typu double double *numbers = malloc(5*sizeof(double)); Pokud se alokace nepodaří NULL (KONTROLOVAT) 24
Příklad: Dealokace (2D) pole Pro dealokaci se používá funkce free Ověření, zda program uvolňuje všechnu alokovanou paměť: valgrind Hlavička funkce void free2d(array2d_t *arr); 25
Příklad: přístup k prvku a jeho modifikace Hlavička funkce double *getitem(array2d_t *arr, int row, int col); Přístup k prvku index_řádku * počet_sloupců + index_sloupce 26
OPERACE S MATICEMI 27
Násobení matice konstantou Napište funkci, která vynásobí matici konstantou Hlavička void mult2dconst(array2d_t *dst, int k); k je konstanta, kterou násobíme 28
Sčítání dvou matic Matice dst a src musí mít stejné rozměry a platí dst = dst + src Hlavička void add2d (array2d_t *dst, array2d_t *src); 29
Násobení matic Mějme 2 matice A a B A = (N, K) B = (K, M) Výsledná matice C C = A * B (N, M) 1. řádek x 1. sloupec 1. řádek x 2. sloupec 2. řádek x 1. sloupec 2. řádek x 2. sloupec 1 2 3 4 5 6 1 2 * 3 4 = 5 6 22 28 49 64 Hlavička void mul2d (array2d_t *c, array2d_t *a, array2d_t *b); 30
Výpis prvků pod hlavní diagonálou Jeden z častých příkladů na zkoušce Budeme vypisovat prvky na modře označených indexech 31
Výpis prvků pod hlavní diagonálou void underdiagonal2d (array2d_t *c, array2d_t *a, array2d_t *b); 32
Děkuji vám za pozornost