65
Procedurálne programovanie: 10 prednáška Gabriela Kosková

Pro cedurálne programovanie: 10 prednáška

  • Upload
    renata

  • View
    67

  • Download
    1

Embed Size (px)

DESCRIPTION

Pro cedurálne programovanie: 10 prednáška. Gabriela Kosková. Obsah. Opakovanie v príkladoch. getchar() - na na čítavanie znakov, nie čísel!. int i ; char c ; ... c = getchar() ; scanf("%c", &c); scanf("%d", &i);. Na čítanie znaku aj pomocou getchar , aj pomocou scanf. - PowerPoint PPT Presentation

Citation preview

Page 1: Pro cedurálne programovanie: 10 prednáška

Procedurálne programovanie:10 prednáška

Gabriela Kosková

Page 2: Pro cedurálne programovanie: 10 prednáška

Obsah

• Opakovanie v príkladoch

Page 3: Pro cedurálne programovanie: 10 prednáška

getchar a scanf

int i;...i = getchar();

getchar() - na načítavanie znakov, nie

čísel!

int i;char c;...c = getchar();scanf("%c", &c);scanf("%d", &i);

Načítanie znaku aj pomocou getchar, aj pomocou scanf

Page 4: Pro cedurálne programovanie: 10 prednáška

scanf a &

int i;char c, str[10], *r;

r = (char *) malloc(5*sizeof(char));

scanf("%d", &i);scanf("%c", &c);scanf("%s", str);scanf("%s", r);

scanf očakáva adresy premenných, do ktorých má zapísať načítanú hodnotuvo funkcii scanf sa vytvorí lokálna premenná ako kópia parametra - adresa, tam sa zapíše načítaná hodnotakeď skončí funkcia, zabudne sa lokálna kópia, teda zabudne sa adresa, no na tej adrese zostane načítaná hodnota

i - premenná,&i - adresa premennej,c - premenná,&c - adresa premennej,str - statická adresa poľa (reťazca znakov)r - adresa poľa (reťazca znakov)

Page 5: Pro cedurálne programovanie: 10 prednáška

Vrátenie hodnoty cez parameter funkciechar najcastejsie_pismeno(char *str, int *pocet){ int hist['Z'-'A'+1], i, i_max; for (i=0; i<'Z'-'A'+1; i++) hist[i] = 0; for (i=0; i<strlen(str); i++) hist[toupper(str[i])-'A']++;

i_max = 0; for (i=0; i<'Z'-'A'+1; i++) if (hist[i]>hist[i_max]) i_max = i; *pocet = hist[i_max]; return (i_max + 'A');}

char str[10], pismeno;int pocet;...pismeno = najcastejsie_pismeno(str, &pocet);

Page 6: Pro cedurálne programovanie: 10 prednáška

& a &&

x = 11;y = 4;

if (x && y) printf("*");if (x & y) printf("+");

Čo vypíše táto časť programu?Pomôcka:11 = (1011)2

4 = (100)2

Logický súčin (&&): nenulové čísla sú PRAVDA, 11, 4 sú nenulové, preto výsledok je PRAVDA vypíše sa *

Bitový súčin (&): súčin po bitoch 0: NEPRAVDA + sa nevypíše

Vypíše sa *

Page 7: Pro cedurálne programovanie: 10 prednáška

Typová konverzia#include <stdio.h>int main(void) { int i = 5, j = 2; float f; f = (float) i / j; printf("Typova konverzia: 1. moznost: %lf\n", f); f = i / (float) j; printf("Typova konverzia: 2. moznost: %lf\n", f); f = (float) i / (float) j; printf("Typova konverzia: 3. moznost: %lf\n", f); f = (float) (i / j); printf("Explicitna typ. konverzia - chybne: %lf\n", f); f = i / j; printf("Implicitna typ. konverzia - chybne: %lf\n", f); return 0; }

Reálne delenie dvoch celých čísel.

Page 8: Pro cedurálne programovanie: 10 prednáška

Vrátenie znaku#include <stdio.h>int main(void) { FILE *fr; int c, cislo, suma = 0; if ((fr = fopen("cisla.txt", "r")) == NULL) { printf("Subor cisla.txt sa nepodarilo otvorit\n"); return 1; } while (1) { while ((c = getc(fr)) == '*') /* citanie znakov '*' */ ; if (c == EOF) break; ungetc(c, fr); /* vratenie znaku spat do suboru */ fscanf(fr, "%d\n", &cislo); suma += cislo; } printf("Sucet cisel je: %d\n", suma); if (fclose(fr) == EOF) printf("Subor sa nepodarilo uzavriet.\n"); return 0; }

Čítanie čísel, ktoré predchádza niekoľko

hviezdičiek

Page 9: Pro cedurálne programovanie: 10 prednáška

Ukazovatele

• Premenné obsahujúce adresy• Definícia ukazovateľa: int *p; • Nikdy nepracujte s ukazovateľom, ktorý ste predtým

nenasmerovali na nejakú zmysluplnú adresu!• Ak potrebujeme zaistiť, aby ukazovateľ neukazoval

na konkrétne miesto priradíme mu hodnotu NULL

Page 10: Pro cedurálne programovanie: 10 prednáška

Ukazovatele

int **p, *q, r;

p: ukazovateľ na ukazovateľ

na int

q: ukazovateľ na int

r: int

17 51 67

p = &q;

51

q = &r;

67 5

r = 5;printf("%p %p %p %p %p %d %p %d %d", &p, &q, &r, p, q, r, *p, *q, **p);

17 51 67 51 67 5 67 5 5

& - vráti adresu premennej

bez operátora - hodnota premennej (ak je hodnotou adresa, tak je to adresa)

* - vráti hodnotu premennej vezme ako adresu a z tej adresy

vráti hodnotu

Page 11: Pro cedurálne programovanie: 10 prednáška

Ukazovatele a polia

int *p, q[5], i=0;for (i=0; i<5; i++) q[i] = i;

19 57 59 61 63 65 103

57

p: ukazovateľ na

int

q: statický ukazovateľ na

int

q[0]: int

q[1]: int

q[4]: int

i: int

p = q;

5

p = q+2; /* to iste ako p = &q[2] */

61

i = *(q+2); /* to iste ako i = q[2] */

2 0 1 2 3 4

Page 12: Pro cedurálne programovanie: 10 prednáška

Ukazovatele

&pole[0] pole+0 pole

&pole[i] pole+i

pole[i] *(pole+i)

pole[0]=10; *pole=10;

pole[10]=70; *(pole+10)=70;

Adresa začiatku poľa

Adresa i-teho prvku poľa

Hodnota i-teho prvku poľa

Priradenie do 1. prvku poľa

Priradenie do 10. prvku poľa

Page 13: Pro cedurálne programovanie: 10 prednáška

zoznam záznamovo knihách (pole)

Kartotéka v knižnici

Joseph Heller

Hlava XXII

1961položky jednoho záznamu

Názov knihy

Meno autora

Rok

jeden záznam o jednej knihe(obsahujúci všetky položky)

Page 14: Pro cedurálne programovanie: 10 prednáška

Príklad: Kartotéka v knižnici

Program načíta celé číslo n, následne načíta n záznamov o knihách a uloží ich do poľa. Potom ponúkne používateľovi menu, kde môže pridávať záznam na koniec, zmazať ktorýkoľvek záznam a

ukončiť program.

Page 15: Pro cedurálne programovanie: 10 prednáška

Kartotéka v knižnici: implementácia

#include <stdio.h>#include <stdlib.h>#include <conio.h>#define N 50 /* dlzka retazcov znakov */#define K 50 /* max. pocet prvkov v kartoteke */

typedef struct {char meno[N];char priezvisko[N];

} AUTOR;

typedef struct {char nazov[N];AUTOR autor;int rok;

} KNIHA;

Page 16: Pro cedurálne programovanie: 10 prednáška

/* nacitanie a pridanie zaznamu na koniec zoznamu*/void pridaj(KNIHA kniznica[], int *n);

/* nacitanie indexu zaznamu a jeho zmazanie */int zmaz(KNIHA kniznica[], int n);

/* vypis zoznamu */void vypis(KNIHA kniznica[], int n);

int main() { int i, n; char c; KNIHA kniznica[K];

printf("Zadajte pocet knih: "); scanf("%d", &n); if (n > K) return 1;

i = 0; /* nacitanie zaznamov do zoznamu */ while (i < n) pridaj(kniznica, &i);

Page 17: Pro cedurálne programovanie: 10 prednáška

do { vypis(kniznica, n); printf("p: pridanie\nz: zmazanie\nk: koniec\n"); c = tolower(getch()); switch(c) { case 'p': pridaj(kniznica, &n); break; case 'z': n = zmaz(kniznica, n); break; }

} while (c != 'k'); return 0;}

Page 18: Pro cedurálne programovanie: 10 prednáška

void pridaj(KNIHA kniznica[], int *n) { if ((*n+1) > K) { printf("Kniznica je plna.\n"); return; } else { printf("Zadajte nazov knihy, autora (meno, "); printf("priezvisko) a rok vydania:\n"); scanf("%s %s %s %d", kniznica[*n].nazov, kniznica[*n].autor.meno, kniznica[*n].autor.priezvisko, &kniznica[*n].rok);

(*n)++;}

}

Page 19: Pro cedurálne programovanie: 10 prednáška

int zmaz(KNIHA kniznica[], int n){ int i;

printf("Zadajte index zaznamu na zmazanie: "); scanf("%d", &i);

if (i < 0 || i >= n-1) { printf("Prvok sa v poli nenachadza.\n"); return n;

}while (i < n-2) {

kniznica[i] = kniznica[i+1];i++;

}return n-1;

}

Page 20: Pro cedurálne programovanie: 10 prednáška

void vypis(KNIHA kniznica[], int n) { int i;

printf("\nKNIZNICA\n\n"); for (i=0; i<n; i++) printf("%s %s: %s (%d)\n", kniznica[i].autor.meno, kniznica[i].autor.priezvisko, kniznica[i].nazov, kniznica[i].rok); printf("\n\n");}

Page 21: Pro cedurálne programovanie: 10 prednáška

Námety na precvičenie

• kartotéka ako spájaný zoznam:typedef struct kniha{ char nazov[N]; AUTOR autor; int rok; struct kniha *dalsia;} KNIHA;

Page 22: Pro cedurálne programovanie: 10 prednáška

Príklad: Zlomky

• oddelený preklad:– modul zlomky: zlomky.c a zlomky.h– modul hlavny: hlavny.c

Page 23: Pro cedurálne programovanie: 10 prednáška

typedef struct { int citatel; int menovatel;} ZLOMOK;

extern ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b);extern void vypis(ZLOMOK a);

zlomky.h

Page 24: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include "zlomky.h"

ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b) { int n; ZLOMOK *z = (ZLOMOK *) malloc(sizeof(ZLOMOK)); z->citatel = a->citatel* b->menovatel + b->citatel * a->menovatel; z->menovatel = a->menovatel * b->menovatel; n = nsd(z->citatel, z->menovatel); z->citatel /= n; z->menovatel /= n; return z;}

void vypis(ZLOMOK *a) { printf("%d / %d\n", a->citatel, a->menovatel); }

static int nsd(int a, int b) { /* o chvilu... */}

zlomky.c

Page 25: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include "zlomky.h"

int main() { ZLOMKY *x, *y, *z; x = (ZLOMOK *) malloc(sizeof(ZLOMOK)); y = (ZLOMOK *) malloc(sizeof(ZLOMOK));

printf("Zadajte dva zlomky: "); scanf("%d %d", &x->citatel, &x->menovatel); scanf("%d %d", &y->citatel, &y->menovatel);

z = spocitaj(x, y); printf("Sucet zlomkov je: "): vypis(z);

return 0;}

hlavny.c

Page 26: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include "zlomky.h"

ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b) { int n; ZLOMOK *z = (ZLOMOK *) malloc(sizeof(ZLOMOK); z->citatel = a->citatel + b->citatel; z->menovatel = a->menovatel + b->menovatel; n = nsd(z->citatel, z->menovatel); z->citatel /= n; z->menovatel /= n;}void vypis(ZLOMOK *a) { printf("%d / %d\n", a->citatel, a->menovatel); }

static int nsd(int a, int b) {

}

#include <stdio.h>#include "zlomky.h"

int main() { ZLOMKY *x, *y, *z; x = (ZLOMOK *) malloc(sizeof(ZLOMOK)); y = (ZLOMOK *) malloc(sizeof(ZLOMOK));

printf("Zadajte dva zlomky: "); scanf("%d %d", &x->citatel, &x->menovatel); scanf("%d %d", &y->citatel, &y->menovatel);

z = spocitaj(x, y); printf("Sucet zlomkov je: "): vypis(z);

return 0;}

typedef struct { int citatel; int menovatel;} ZLOMOK;

extern ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b);extern void vypis(ZLOMOK a);

zlomky.c

zlomky.h

hlavny.c

Page 27: Pro cedurálne programovanie: 10 prednáška

NSD a NSN

program načíta dve celé čísla a vypíše ich najväčší spoločný deliteľ (NSD) a najmenší spoločný násobok (NSN).

Page 28: Pro cedurálne programovanie: 10 prednáška

NSD

• platí– NSD(0, 0) = 0 – NSD(a, b) = NSD(b, a)– NSD(a, b) = NSD(-a, b)– NSD(a, 0) = ABS(a)

budeme uvažovať len nezáporné čísla

• algorimtus: – Eukleidos popísal tento algoritmus v knihe Základy (okolo r. 300

p.n.l.). Algoritmus je založený na platnosti rekurzívneho vzťahu: NSD(a, b) = NSD(b, a % b)

Page 29: Pro cedurálne programovanie: 10 prednáška

Dôkaz algoritmu

• Predpokladajme, že:– a, b - čísla, ktorých NSD chceme nájsť– zvyšok po delení a/b je t, teda a = qb + t

• Potom – každý spoločný deliteľ a a b delí t bezo zvyšku

(lebo t = a - qb)– podobne, každý spoločný deliteľ b a t tiež delí a– Potom aj najväčší spoločný deliteľ a a b je tiež najväčším

spoločným deliteľom b a t– Potom sa dá ďalej pokračovať s b a t namiesto a a b.

Keďže t je menšie v absolútnej hodnote, pokým t nedosiahne 0

Page 30: Pro cedurálne programovanie: 10 prednáška

int nsd(int a, int b){ int pom;

do { if (a < b) { pom = a; a = b; b = pom; } a %= b; } while (a);

return b;}

NSD

Page 31: Pro cedurálne programovanie: 10 prednáška

NSN

• najmenšie kladné číslo, ktoré je násobkom čísel a, b

• algorimtus: – vychádza zo vzťahu:a * b = NSD(a, b) * NSN(a, b)

int nsn(int a, int b) { return a * b / nsd(a, b);}

Page 32: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>

int nsd(int a, int b);int nsn(int a, int b);

void main(void){ int m, n;

scanf("%d %d",&m,&n); printf("NSD(%d,%d) = %d\n",m, n, nsd(m, n)); printf("NSN(%d,%d) = %d\n",m, n, nsn(m, n));}

NSD a NSN

Page 33: Pro cedurálne programovanie: 10 prednáška

Príklad rozvrh

• dvojrozmerné pole • práca so súborom• štruktúra• parametre funkcie main

Program načíta zo súboru údaje o hodinách v rozvrhu

a vypíše rozvrh na obrazovku

PoUtStŠtPiSoNe

MatematikaMrkvička3 hodiny

Page 34: Pro cedurálne programovanie: 10 prednáška

Vstupný súbor a štruktúra• Súbor:

– deň hodina– skratka predmetu– meno učiteľa– počet hodín

• Štruktúra:– predmet– ucitel– cast:

• -1: voľno• 0: začiatok vyuč. hodiny• 1: stred alebo koniec vyuč.hodiny

• Námet na precvičenie: – Rozvrh ako pole spájaných zoznamov

1 1MATMaly42 3FYZVelky23 2ANGPekna33 3TELVesely105 3SJZeleny1

vyuč. hodina: 4 riadne hodiny

4 záznamy:MATMaly0MATMaly1MATMaly1MATMaly1

Page 35: Pro cedurálne programovanie: 10 prednáška

Rozvrh: príklad výstupu

ROZVRH

-----------------------------------------------------------------------| Pondelok| MAT, Maly | |-----------------------------------------------------------------------| Utorok| | | FYZ,Velky | |-----------------------------------------------------------------------| Streda| | ANG,Pekna| TEL,Vesel |-----------------------------------------------------------------------| Stvrtok| | | | | |-----------------------------------------------------------------------| Piatok| | | SJ,Zelen| | |-----------------------------------------------------------------------| Sobota| | | | | |-----------------------------------------------------------------------| Nedela| | | | | |-----------------------------------------------------------------------

Page 36: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include <string.h>#define N 6 /* pocet pismen v slove (5 znakov) */#define ND 7 /* pocet dni */#define NH 5 /* pocet hodin */#define SUBOR "subor.txt" /* default nazov subora */

typedef enum { pondelok, utorok, streda, stvrtok, piatok, sobota, nedela};

typedef struct { char predmet[N]; char ucitel[N]; int cast; /* -1 volno, 0 zaciatok, 1 stred,koniec */} HODINA;

char *dni[] = {"Pondelok", "Utorok", "Streda", "Stvrtok", "Piatok", "Sobota", "Nedela"};

Page 37: Pro cedurálne programovanie: 10 prednáška

void inicializuj(HODINA rozvrh[][NH]); int nacitaj(HODINA rozvrh[][NH], char subor[]); void vypis(HODINA rozvrh[][NH]);

int main (int argc, char *argv[]) {HODINA rozvrh[ND][NH];char subor[N];

if (argc == 2) strcpy(subor, argv[1]);

elsestrcpy(subor, SUBOR);

inicializuj(rozvrh);if (nacitaj(rozvrh, subor)) {

return 1;}

vypis(rozvrh);return 0;

}

Page 38: Pro cedurálne programovanie: 10 prednáška

void inicializuj(HODINA rozvrh[][NH]) {int i, j;

for(i=0; i<ND; i++) for(j=0; j<NH; j++)

rozvrh[i][j].cast = -1;}

Page 39: Pro cedurálne programovanie: 10 prednáška

/* nacitanie rozvrhu zo subora */int nacitaj(HODINA rozvrh[][NH], char subor[]) { int i, den, hodina, dlzka; FILE *f;

if ((f = fopen(subor, "r")) == NULL) { printf("Nepodarilo sa otvorit subor %s.\n", subor); return 1; }

while(!feof(f)) { fscanf(f, "%d %d", &den, &hodina); den--; hodina--;

fscanf(f, "%s", rozvrh[den][hodina].predmet); if (strlen(rozvrh[den][hodina].predmet) > 5) rozvrh[den][hodina].predmet[5] = '\0'; /*5 zn.*/

fscanf(f, "%s", rozvrh[den][hodina].ucitel); if (strlen(rozvrh[den][hodina].ucitel) > 5) rozvrh[den][hodina].ucitel[5] = '\0'; /*5 zn.*/

fscanf(f, "%d", &dlzka); rozvrh[den][hodina].cast = 0; /*zaciatok vyuc. h.*/

Page 40: Pro cedurálne programovanie: 10 prednáška

/* ak ma vyuc.hod. viac ako 1 hodinu, naplnia sa dalsie zaznamy */ if (dlzka > 1) { for (i=1; i<dlzka && hodina+i < NH; i++) { rozvrh[den][hodina+i] = rozvrh[den][hodina]; rozvrh[den][hodina+i].cast = 1; } } } if(fclose(f) == EOF) printf("Subor sa nepodarilo zatvorit.\n"); return 0;}

Page 41: Pro cedurálne programovanie: 10 prednáška

void vypis(HODINA rozvrh[][NH]) { int i, j;

printf("\nROZVRH\n\n");

for(i=0; i<ND; i++) {

/* horna ciara + ciary oddelujuce dni */ for(j=0; j<NH*12+1+10; j++) putchar('-');

printf("\n|%9s", dni[i]); /* oznacenie dna */

Page 42: Pro cedurálne programovanie: 10 prednáška

/* riadok */ for(j=0; j<NH; j++) { if (j == 0 || rozvrh[i][j].cast < 1) putchar('|'); /* ciara pred vyuc. hod. */ else putchar(' '); /* vo vnutri v.h. ' ' */ if (rozvrh[i][j].cast == 0) /* vypis udajov */ printf("%5s,%5s", rozvrh[i][j].predmet, rozvrh[i][j].ucitel); else printf(" "); /* medzery */ if (j == NH-1) putchar('|'); /* koniec dna */ }

putchar('\n'); /* prechod na dalsi riadok-den */ }

/* dolna ciara */ for(j=0; j<NH*12+1+10; j++) putchar('-'); printf("\n");}

Page 43: Pro cedurálne programovanie: 10 prednáška

Binárne operácie#include <stdio.h>int main(){ printf("1 << 1 = %d\t%x\n", 1 << 1, 1 << 1); printf("1 << 7 = %d\t%x\n", 1 << 7, 1 << 7); printf("1024 >> 9 = %d\t%x\n",1024 >> 9,1024 >>9);

printf("13 & 6 = %d\t%x\n", 13 & 6, 13 & 6); printf("13 | 6 = %d\t%x\n", 13 | 6, 13 | 6); printf("13 ^ 6 = %d\t%x\n", 13 ^ 6, 13 ^ 6);

printf("2 & 1 = %d\t%x\n", 2 & 1, 2 & 1); printf("2 | 1 = %d\t%x\n", 2 | 1, 2 | 1); printf("2 ^ 1 = %d\t%x\n", 2 ^ 1, 2 ^ 1); return 0;}

1 << 1 = 2 0x21 << 7 = 128 0x801024 >> 9 = 2 0x2

13 & 6 = 4 0x413 | 6 = 15 0xf13 ^ 6 = 11 0xb

2 & 1 = 0 02 | 1 = 3 0x32 ^ 1 = 3 0x3

128 = 27

1024 = 21013: 1101 6: 110

1: 012: 10

Page 44: Pro cedurálne programovanie: 10 prednáška

Binárne operácie#include <stdio.h>#define vytvorit_cislo(i) (1 << (i)) #define rad(x, i) (((x) >> (i)) & 1)

unsigned invert(unsigned x, int i, int n) { unsigned j; for (j=i; j < i+n; j++) { if (rad(x, j) == 0) x = x | (vytvorit_cislo(j)); else x = x & (~(vytvorit_cislo(j))); } return x;}

void vypis(unsigned x) { if (x > 0) { vypis(x >> 1); printf("%d", x & 1); }}

vytvori cislo s 1 na pozícii i, ostatne su 0

vrati cislicu i-teho radu cisla x

Rekurzívny výpis

Page 45: Pro cedurálne programovanie: 10 prednáška

Vyhľadávanie v usporiadanom poli

program načíta do poľa usporiadanú postupnosť čísel a hodontu, ktorú chce v postupnosti (v poli) vyhľadať (nájsť jej index): použije sekvenčné a binárne vyhľadávanie

Page 46: Pro cedurálne programovanie: 10 prednáška

Sekvenčné vyhľadávanie

• najjednoduchšie vyhľadávanie:– od začiatku poľa postupne zväčšuje index pokým

nepríde na hodnotu, korá je väčšia alebo rovná alebo pokým nepríde na koniec poľa

• neefektívne

Page 47: Pro cedurálne programovanie: 10 prednáška

int sekvencne(int pole[], int n, int x) { int i=0;

while(i < n && pole[i] < x) i++; if(pole[i] == x) return i; return -1;}

Sekvenčné vyhľadávanie

Page 48: Pro cedurálne programovanie: 10 prednáška

Binárne vyhľadávanie

• nájdenie stredu intervalu - ak je hľadaná hodnota menšia ako hodnota stredného prvku hľadanie v ľavej polovici, inak v pravej polovici

1 2 3 4 5 6 7 8 9 10 11 120 1 2 3 4 5 6 7 8 9 10 11

hľadáme pozíciu hodnoty 7

Page 49: Pro cedurálne programovanie: 10 prednáška

int binarne(int pole[], int n, int x){ int m, l = 0, r = n-1;

while (l <= r) { m = (l + r) / 2;

if (x == pole[m]) return m; if (x < pole[m]) r = m - 1; else l = m + 1; }

if (pole[m] == x) return m; else return -1;}

Page 50: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include <stdlib.h>int sekvencne(int pole[], int n, int x); int binarne(int pole[], int n, int x);

int main(){ int p[100], i, n, x, vysl; char c; printf("Zadaj pocet prvkov pola (<100): "); scanf("%d", &n);

if (n >= 100) { printf("Prilis velky pocet prvkov...\n"); return 1; } for (i=0; i<n; i++) { printf("p[%d]: ", i); scanf("%d", &p[i]); }

Page 51: Pro cedurálne programovanie: 10 prednáška

printf("Zadajte hodnotu, ktora sa ma vyhladat: "); scanf("%d", &x); while(getchar() != '\n'); printf("Vyhladavat Binarne alebo Sekvencne? [b/s]: "); c = getchar();

printf("%c\n", c); if ((c = tolower(c)) == 's') vysl = sekvencne(p, n, x); else if (c == 'b') vysl = binarne(p, n, x); else { printf("Zadali ste nespravnu hodnotu.\n"); return 1; }

if (vysl > -1) printf("Index hladanej hodnoty je %d.\n",vysl); else printf("Hladana hodnota sa v poli nenachadza.\n"); return 0;}

Page 52: Pro cedurálne programovanie: 10 prednáška

Koľko písmen treba doplniť do slova aby vznikol palindrom?

program načíta slovo (pole znakov) a zistí koľko najmenej písmen treba do slova doplniť tak, aby sme z neho dostali palindrom

Page 53: Pro cedurálne programovanie: 10 prednáška

Čo je to palindrom?

• slovo, ktoré je rovnaké keď sa číta odpredu aj odzadu

• napr. – radar, – ťahať, – jelenovipivonelej, – kobylamamalybok

Page 54: Pro cedurálne programovanie: 10 prednáška

funkcia palindrom

• Pre dĺžku menšiu ako 1, je výsledok 0 • Inak:

– Ak sa prvé písmeno rovná poslednému v slove, rekurzívne volaj funkciu palindrom so skráteným slovom bez 1. a posl. písmena

– Inak je potrebné pridať jedno písmeno (buď na začiatok to posledné, alebo na koniec to prvé). Ktorá z týchto možností je lepšia nevieme, preto treba vyskúšať obe možnosti:

• m1 je výsledok rekurzívneho volania palindrom so slovom s bez prvého písmena,

• m2 je výsledok rekurzívneho volania minlength so slovom s bez posledného písmena.

• výsledok je potom 1 + min(m1, m2)

Page 55: Pro cedurálne programovanie: 10 prednáška

int palindrom(char p[], int n){ if (n <= 1) return 0; if (p[0] == p[n-1]) return palindrom(&p[1], n-2);

return 1 + min(palindrom(&p[0], n-1), palindrom(&p[1], n-1));}

funkcia palindrom

Page 56: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#define min(x, y) (x<y ? x : y)#define N 100

int palindrom(char p[], int n);

int main(){

int n = 0; char c, p[N];

printf("Zadajte slovo: "); while((c = getchar()) != '\n') p[n++] = c; printf("Na palindrom je potrebne doplnit %d pismen.\n", palindrom(p, n)); return 0;}

Page 57: Pro cedurálne programovanie: 10 prednáška

Hodnota polynómu v danom bode

program načíta koeficienty polynómu a hodnotu premennej x a vypočíta hodnotu polynómu v bode x.

Page 58: Pro cedurálne programovanie: 10 prednáška

Hodnota polynómu v danom bode

• Efektívny algoritmus znižujúci na minimum počet násobení je známy ako Hornerova schéma:a0 + a1x + a2x2 + ... + an-1xn-1 + anxn =a0 + x (a1 + x (a2 + x (... + x (an-1 + anx)...)))

• polynóm stupňa N tak môže byť vyhodnotený len s použitím:– N-1 operácií násobenia,– N operácií sčítania

Page 59: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include <stdlib.h>float horner(float p[], int n, float x);void nacitaj(float p[], int n);int main(){ int n, i; float x, *p;

printf("Zadajte stupen polynomu: "); scanf("%d", &n); n++; if ((p = (float *) malloc(n * sizeof(float))) == NULL) { printf("Nepodarilo sa alokovat pol.\n"); return 1; } nacitaj(p, n); printf("Zadajte hodnotu premennej x: "); scanf("%f", &x); printf("hodnota polynomu je: %f\n", horner(p, n, x)); return 0;}

Page 60: Pro cedurálne programovanie: 10 prednáška

float horner(float p[], int n, float x){ int i; float v = p[n-1];

for (i = n-2; i >= 0; i--) v = x * v + p[i];

return v;} void nacitaj(float p[], int n)

{ int i; for (i=0; i<n; i++) { printf("p[%d]: ", i); scanf("%f", &p[i]); }}

Hodnota polynómu v danom bode: Hornerova schéma

Page 61: Pro cedurálne programovanie: 10 prednáška

Prevod rímskych číslic do desiatkovej sústavy

program do poľa načíta rímske číslo a prevedie ho na desiatkové

Page 62: Pro cedurálne programovanie: 10 prednáška

Prevod rímskych číslic do desiatkovej sústavy

• premenné:– digit: rímska číslica prevedená na desiatkové číslo– next_digit: nasledujúca rímska číslica - prevedená

na desiatkové číslo– decimal: časť prevedeného čísla (inicializovaná na 0)

• algoritmus:prečíta sa prvé písmeno digitv cykle: nasledujúce písmeno next_digit

ak je digit < next_digit: z decimal sa odpočíta digitinak: do decimal sa pripočíta digitdigit next_digit

Page 63: Pro cedurálne programovanie: 10 prednáška

#include <stdio.h>#include <stdlib.h>#define N 10

int skonvertuj_pismeno(char r);int r2d(char roman[], int n);

int main() { char c, roman[N]; int n;

printf("Zadajte rimske cislo: "); n = 0; while(n < N && (c=getchar()) != '\n') roman[n++] = c; roman[n] = '\0';

printf("%s: %d\n", roman, r2d(roman, n)); return 0;}

Page 64: Pro cedurálne programovanie: 10 prednáška

int skonvertuj_pismeno(char r){ switch(toupper(r)) { case 'I': return 1; break; case 'V': return 5; break; case 'X': return 10; break; case 'L': return 50; break; case 'C': return 100; break; case 'D': return 500; break; case 'M': return 1000; break; } printf("Neplatna konverzia znaku %c.\n", r); exit(1);}

Prevod rímskych číslic do desiatkovej sústavy

Page 65: Pro cedurálne programovanie: 10 prednáška

int r2d(char roman[], int n){ int decimal = 0, i, digit, next_digit;

digit = skonvertuj_pismeno(roman[0]);

i = 1; while (roman[i] != '\0') { next_digit = skonvertuj_pismeno(roman[i]);

if(next_digit > digit) decimal = decimal - digit; else decimal = decimal + digit;

digit = next_digit; i++ } return decimal+digit;}