Jazyk C (príklady) - Algoritmy: Rozdiel medzi revíziami

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání
 
(6 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených)
Riadok 23: Riadok 23:
  
 
===Absolútna hodnota===
 
===Absolútna hodnota===
'''Zadanie:'''
+
;Zadanie: Vieme, že absolútna hodnota je definovaná ako vzdialenosť čísla od začiatku súradnicového systému (resp. od nuly). Nakreslite vývojový diagram, ktorý by znázorňoval výpočet absolútnej hodnoty.
Vieme, že absolútna hodnota je definovaná ako vzdialenosť čísla od začiatku súradnicového systému (resp. od nuly). Nakreslite vývojový diagram, ktorý by znázorňoval výpočet absolútnej hodnoty.
 
  
'''Analýza problému:'''
+
;Analýza problému: Pre absolútnu hodnotu reálnych čísel platí:
Pre absolútnu hodnotu reálnych čísel platí:
+
* abs(x) = x
*abs(x) = x
+
* abs(-x) = x
*abs(-x) = x
 
 
Inak povedané, pre x>=0, je absolútna hodnota x rovná práve x, pre x<0 je absolútna hodnota x rovná -1*x.  
 
Inak povedané, pre x>=0, je absolútna hodnota x rovná práve x, pre x<0 je absolútna hodnota x rovná -1*x.  
 
Teda, stačí nám zistiť, či je x menšie ako nula.
 
Teda, stačí nám zistiť, či je x menšie ako nula.
  
 
[[Súbor:78 2 alg1.png|240px|none]]
 
[[Súbor:78 2 alg1.png|240px|none]]
 +
  
 
===Kvadratická rovnica===
 
===Kvadratická rovnica===
'''Zadanie:'''
+
;Zadanie: Navrhnite algoritmus výpočtu koreňov kvadratickej rovnice ax2+bx+c=0. Vstupom do algoritmu budú koeficienty a, b, c, a výstupom budú korene kvadratickej rovnice x1,2.
Navrhnite algoritmus výpočtu koreňov kvadratickej rovnice ax2+bx+c=0. Vstupom do algoritmu budú koeficienty a, b, c, a výstupom budú korene kvadratickej rovnice x1,2.
 
  
'''Analýza problému:'''
+
;Analýza problému: Riešenie tejto rovnice je známe, úlohou je tento problém znázorniť v podobe vývojového diagramu. Vieme, že kvadratická rovnica má dva korene (x1 a x2). Tieto korene môžu byť rôzne, alebo riešením je jeden dvojnásobný koreň. Toto zistíme pomocou výpočtu diskriminantu kvadratickej rovnice. Diskriminant je definovaný ako D=b2-4ac
Riešenie tejto rovnice je známe, úlohou je tento problém znázorniť v podobe vývojového diagramu. Vieme, že kvadratická rovnica má dva korene (x1 a x2). Tieto korene môžu byť rôzne, alebo riešením je jeden dvojnásobný koreň. Toto zistíme pomocou výpočtu diskriminantu kvadratickej rovnice. Diskriminant je definovaný ako D=b2-4ac
 
 
Rozoberme si jednotlivé prípady riešenia.
 
Rozoberme si jednotlivé prípady riešenia.
 
+
*D>0 : Rovnica má dva korene: x1=(-b+D1/2)/2a, x2=(-b-D1/2)/2a
*D>0 : Rovnica má dva korene: x1=(-b+D1/2)/4ac, x2=(-b-D1/2)/4ac
+
*D=0 : Rovnica má jeden dvojnásobný koreň: x1,2=-b/2a
*D=0 : Rovnica má jeden dvojnásobný koreň: x1,2=-b/4ac
 
 
*D<0 : Rovnica má riešenie na množine komplexných čísel:
 
*D<0 : Rovnica má riešenie na množine komplexných čísel:
Vieme, že i2=-1. (i je komplexná jednotka). Potom výpočet druhej odmocniny diskriminantu je (D)1/2=(i2 * (-D))1/2=i*(-D) ½ (poznámka: D<0). Teda korene kvadratickej rovnice budú x1=(-b+iD1/2)/4ac, x2=(-b-iD1/2)/4ac
+
Vieme, že i2=-1. (i je komplexná jednotka). Potom výpočet druhej odmocniny diskriminantu je (D)1/2=(i2 * (-D))1/2=i*(-D) ½ (poznámka: D<0). Teda korene kvadratickej rovnice budú x1=(-b+iD1/2)/2a, x2=(-b-iD1/2)/2a
  
  
 
[[Súbor:80 2 alg2.png|480px|none]]
 
[[Súbor:80 2 alg2.png|480px|none]]
 
  
 
===Maximum z 3 hodnôt===
 
===Maximum z 3 hodnôt===
'''Zadanie:'''
+
;Zadanie: V predajni skrípt majú 3 skriptá, o ktoré máme záujem. Cena skrípt je a, b, c Sk. Navrhnite algoritmus, ktorý nájde najdrahšie skriptá; teda skriptá s maximálnou cenou.
V predajni skrípt majú 3 skriptá, o ktoré máme záujem. Cena skrípt je a, b, c Sk. Navrhnite algoritmus, ktorý nájde najdrahšie skriptá; teda skriptá s maximálnou cenou.
 
  
'''Analýza problému:'''
+
;Analýza problému: V prípade, ak máme zistiť maximálnu (alebo minimálnu) hodnotu z troch čísel, musíme každé číslo porovnať s každým iným číslom. Teda, spolu budeme robiť 3 porovnania (a<->b, a<->c, b<->c). Nemá zmysel porovnávať ab a ba, lebo toto sú totožné porovnania. Ak teda máme zistiť najväčšie číslo z a, b, c, môžeme postupovať napríklad nasledovne: Najskôr porovnáme : a>b. Ak toto platí, potom porovnáme a>c. V prípade ak aj toto platí, tak maximum je a. Keby platilo že: a>b a c>a, potom vieme, že maximum je c. Takto by sme mohli pokračovať ďalej.
V prípade, ak máme zistiť maximálnu (alebo minimálnu) hodnotu z troch čísel, musíme každé číslo porovnať s každým iným číslom. Teda, spolu budeme robiť 3 porovnania (a<->b, a<->c, b<->c). Nemá zmysel porovnávať ab a ba, lebo toto sú totožné porovnania. Ak teda máme zistiť najväčšie číslo z a, b, c, môžeme postupovať napríklad nasledovne:
 
Najskôr porovnáme : a>b. Ak toto platí, potom porovnáme a>c. V prípade ak aj toto platí, tak maximum je a. Keby platilo že: a>b a c>a, potom vieme, že maximum je c. Takto by sme mohli pokračovať ďalej.
 
  
  
 
[[Súbor:82 2 alg3.png|360px|none]]
 
[[Súbor:82 2 alg3.png|360px|none]]
 +
  
 
===Opakované načítanie===
 
===Opakované načítanie===
'''Zadanie:'''
 
Na faktúre je údaj o počte položiek a samotné položky (položka obsahuje o.i. aj cenu v Sk). Ak viete koľko je na faktúre položiek, navrhnite algoritmus, ktorý vypočíta celkovú sumu položiek faktúry. Prvý vstupný údaj bude číslo pocet, ktoré nám hovorí o počte nasledujúcich položiek. Následne sa načíta pocet položiek ( – celých čísel symbolizujúcim cenu položky). Navrhnite algoritmus, ktorý vypočíta výslednú sumu ceny všetkých položiek.
 
  
'''Analýza problému:'''
+
;Zadanie: Na faktúre je údaj o počte položiek a samotné položky (položka obsahuje o.i. aj cenu v Sk). Ak viete koľko je na faktúre položiek, navrhnite algoritmus, ktorý vypočíta celkovú sumu položiek faktúry. Prvý vstupný údaj bude číslo pocet, ktoré nám hovorí o počte nasledujúcich položiek. Následne sa načíta pocet položiek ( – celých čísel symbolizujúcim cenu položky). Navrhnite algoritmus, ktorý vypočíta výslednú sumu ceny všetkých položiek.
V tomto prípade nikdy popredu nevieme, koľko budeme načítavať položiek. Tento údaj sa dozvieme až v momente, keď načítame prvý údaj. Úlohou bude teda navrhnúť algoritmus, ktorý by načítal požadovaný počet položiek (počet položiek môže byť od 0 až po ľubovoľne veľké konečné číslo).
 
  
Na riešenie tohto problému využijeme cyklus. Tento cyklus sa bude opakovať toľkokrát, koľko položiek máme načítať. Pri každom opakovaní cyklu načítame jednu položku (položku označme ako premennú a) a jej hodnotu pripočítame k výslednej sume. Ďalším algoritmickým problémom je zabezpečiť, aby sa tento cyklus vykonával presne pocet krát. Tu využijeme prvý vstupný údaj pocet. Pri každej iterácii (opakovaní) cyklu sa hodnota premennej pocet zníži o 1. Cyklus budeme opakovať dovtedy, pokiaľ bude premenná pocet rôzna od nuly. Na výpočet súčtu všetkých položiek využijeme premennú suma, ktorú na začiatku vynulujeme (priradíme jej hodnotu 0).
+
;Analýza problému: V tomto prípade nikdy popredu nevieme, koľko budeme načítavať položiek. Tento údaj sa dozvieme až v momente, keď načítame prvý údaj. Úlohou bude teda navrhnúť algoritmus, ktorý by načítal požadovaný počet položiek (počet položiek môže byť od 0 až po ľubovoľne veľké konečné číslo). Na riešenie tohto problému využijeme cyklus. Tento cyklus sa bude opakovať toľkokrát, koľko položiek máme načítať. Pri každom opakovaní cyklu načítame jednu položku (položku označme ako premennú a) a jej hodnotu pripočítame k výslednej sume. Ďalším algoritmickým problémom je zabezpečiť, aby sa tento cyklus vykonával presne pocet krát. Tu využijeme prvý vstupný údaj pocet. Pri každej iterácii (opakovaní) cyklu sa hodnota premennej pocet zníži o 1. Cyklus budeme opakovať dovtedy, pokiaľ bude premenná pocet rôzna od nuly. Na výpočet súčtu všetkých položiek využijeme premennú suma, ktorú na začiatku vynulujeme (priradíme jej hodnotu 0).
  
  
 
[[Súbor:84 2 alg4.png|360px|none]]
 
[[Súbor:84 2 alg4.png|360px|none]]
 +
 +
 +
===Násobenie===
 +
 +
;Zadanie: V počítačoch (na hardvérovej úrovni) sa operácia násobenia vykoná pomocou opakovaného sčítavania dvoch hodnôt. Vytvorte algoritmus, ktorý by násobil dve celé čísla pomocou opakovaného sčítavania.
 +
 +
;Analýza problému: Na riešenie problému nemôžeme použiť operáciu násobenia (*), musíme použiť operáciu sčítavania (+). Zoberme si príklad: x=5*3. Tu budeme 3 krát pripočítame hodnotu 5 do premennej x, ktorú musíme najskôr vynulovať. Teda x=5+5+5=15. Vo všeobecnosti máme x=a*b=a+a+...+a : sčítavanie robíme b krát. Z uvedeného vyplýva, že nemôžeme pevne napísať, koľkokrát sa a pripočíta do premennej x. Tu bude vhodné využiť nejaký cyklus. V každom cykle sa do premennej x pripočíta hodnota a. Počet opakovaní cyklu je b. V každej iterácii cyklu hodnotu premennej b znížime o 1. Cyklus ukončíme, ak sa b=0.
 +
 +
 +
[[Súbor:86 2 alg5.png|300px|none]]
 +
 +
===Prvočíslo===
 +
;Zadanie: Navrhnite algoritmus, ktorý zistí, či zadané číslo a je prvočíslo.
 +
 +
;Analýza problému: Prvočíslo je číslo, ktoré je delitelné iba číslom 1 a sebou samým. Pri testovaní čísla a na prvočíselnosť postupne celočíselne deliť číslo a číslami del=2, 3, ...n. Ak pri všetkých deleniach bude nejaký zvyšok (a sa nedá deliť číslom del), povieme že číslo a je prvočíslo. Ak v priebehu delenia zistíme, že a je delitené číslom del bezo zvyšku, algoritmus ukončíme, a povieme že a nie je prvočíslo. Ďalší problém je určiť, dokedy má zmysel zväčšovať deliteľ del. V predchádzajúcom texte sme del zvyšovali po hodnotu n. Úlohou je odhadnúť vhodné n. Pokúsme sa postupovať nasledovne: ako prvý deliteľ je del=2. Teda delíme a číslom del=2. Výsledok po tomto delení označme podiel. Ak budeme premennú del zvyšovať, nebude mať zmysel zväčšovať ju nad hodnotu podiel=a/2, pretože číslo a nemôže deliť žiadne číslo, ktoré je väčšie ako a/2. Ďalej, nech del=3. Ak číslo del (del=3) nedelí číslo a, hranica delenia – n sa zníži na hodnotu a/3, pretože žiadne číslo väčšie ako a/3 nemôže deliť a bezo zvyšku. Z uvedeného nám vyplýva, že hranicu n môžeme určiť nasledovne: Pri každom delení si zapamätáme podiel. Ďalšie delenie robíme iba ak podiel>del. V algoritme použijeme ešte jednu premennú prvocislo. Táto premenná nám bude hovoriť, či je číslo prvočíslo alebo nie je. Na začiatku má hodnotu 1 – teda predpokladáme, že číslo je prvočíslo. V prípade, ak počas delenia zistíme, že nejaké číslo del delí a bezo zvyšku, premennej prvocislo priradíme hodnotu 0. Vyhlásime, že a nie je prvočíslo.
 +
 +
; Ukážka:
 +
*a=23
 +
*a del podiel
 +
*23 / 2 = 11 zv 1
 +
*23 / 3 = 7 zv 2
 +
*23 / 4 = 5 zv 3
 +
*23 / 5 = 4 zv 3 del > podiel; koniec; a je prvočíslo, pretože ani jeden zvyšok po delení nebol 0
 +
*23 je prvočíslo.
 +
 +
 +
[[Súbor:88 2 alg6.png|480px|none]]

Aktuálna revízia z 20:15, 6. marec 2021


Základy informatiky - jazyk C


Riešené príklady

Algoritmy

Prvé programy

Podmienky

Cykly

Polia

Funkcie

Súbor

Vzorové príklady

Neriešené príklady


zdroj: Juraj Ďuďák, Zbierka úloh z algoritmizácie pre predmet Základy informatiky

ISBN: 978-80-8075-199-9

Obsah

V tejto kapitole budú ukázaná tvorba jednoduchých vývojových diagramov. Budú ukázané základné prvky algoritmizácie úloh, použitie rozhodovania, opakovania istého počtu operácií. K zvládnutiu tejto kapitoly sa predpokladá znalosť grafických značiek použitých pri tvorbe vývojových diagramov.

Grafické značky vývojových diagramov

Medzi základné stavebné bloky vývojových diagramov (VD) patria bloky, ktoré reprezentujú

  • začiatok / koniec VD
  • vykonávací blok
  • rozhodovací blok
  • spojka
  • vstup / výstup dát
  • orientované spojnice blokov

[Vývojové stavebné bloky]


Príklady

Absolútna hodnota

Zadanie
Vieme, že absolútna hodnota je definovaná ako vzdialenosť čísla od začiatku súradnicového systému (resp. od nuly). Nakreslite vývojový diagram, ktorý by znázorňoval výpočet absolútnej hodnoty.
Analýza problému
Pre absolútnu hodnotu reálnych čísel platí:
  • abs(x) = x
  • abs(-x) = x

Inak povedané, pre x>=0, je absolútna hodnota x rovná práve x, pre x<0 je absolútna hodnota x rovná -1*x. Teda, stačí nám zistiť, či je x menšie ako nula.

78 2 alg1.png


Kvadratická rovnica

Zadanie
Navrhnite algoritmus výpočtu koreňov kvadratickej rovnice ax2+bx+c=0. Vstupom do algoritmu budú koeficienty a, b, c, a výstupom budú korene kvadratickej rovnice x1,2.
Analýza problému
Riešenie tejto rovnice je známe, úlohou je tento problém znázorniť v podobe vývojového diagramu. Vieme, že kvadratická rovnica má dva korene (x1 a x2). Tieto korene môžu byť rôzne, alebo riešením je jeden dvojnásobný koreň. Toto zistíme pomocou výpočtu diskriminantu kvadratickej rovnice. Diskriminant je definovaný ako D=b2-4ac

Rozoberme si jednotlivé prípady riešenia.

  • D>0 : Rovnica má dva korene: x1=(-b+D1/2)/2a, x2=(-b-D1/2)/2a
  • D=0 : Rovnica má jeden dvojnásobný koreň: x1,2=-b/2a
  • D<0 : Rovnica má riešenie na množine komplexných čísel:

Vieme, že i2=-1. (i je komplexná jednotka). Potom výpočet druhej odmocniny diskriminantu je (D)1/2=(i2 * (-D))1/2=i*(-D) ½ (poznámka: D<0). Teda korene kvadratickej rovnice budú x1=(-b+iD1/2)/2a, x2=(-b-iD1/2)/2a


80 2 alg2.png

Maximum z 3 hodnôt

Zadanie
V predajni skrípt majú 3 skriptá, o ktoré máme záujem. Cena skrípt je a, b, c Sk. Navrhnite algoritmus, ktorý nájde najdrahšie skriptá; teda skriptá s maximálnou cenou.
Analýza problému
V prípade, ak máme zistiť maximálnu (alebo minimálnu) hodnotu z troch čísel, musíme každé číslo porovnať s každým iným číslom. Teda, spolu budeme robiť 3 porovnania (a<->b, a<->c, b<->c). Nemá zmysel porovnávať ab a ba, lebo toto sú totožné porovnania. Ak teda máme zistiť najväčšie číslo z a, b, c, môžeme postupovať napríklad nasledovne: Najskôr porovnáme : a>b. Ak toto platí, potom porovnáme a>c. V prípade ak aj toto platí, tak maximum je a. Keby platilo že: a>b a c>a, potom vieme, že maximum je c. Takto by sme mohli pokračovať ďalej.


82 2 alg3.png


Opakované načítanie

Zadanie
Na faktúre je údaj o počte položiek a samotné položky (položka obsahuje o.i. aj cenu v Sk). Ak viete koľko je na faktúre položiek, navrhnite algoritmus, ktorý vypočíta celkovú sumu položiek faktúry. Prvý vstupný údaj bude číslo pocet, ktoré nám hovorí o počte nasledujúcich položiek. Následne sa načíta pocet položiek ( – celých čísel symbolizujúcim cenu položky). Navrhnite algoritmus, ktorý vypočíta výslednú sumu ceny všetkých položiek.
Analýza problému
V tomto prípade nikdy popredu nevieme, koľko budeme načítavať položiek. Tento údaj sa dozvieme až v momente, keď načítame prvý údaj. Úlohou bude teda navrhnúť algoritmus, ktorý by načítal požadovaný počet položiek (počet položiek môže byť od 0 až po ľubovoľne veľké konečné číslo). Na riešenie tohto problému využijeme cyklus. Tento cyklus sa bude opakovať toľkokrát, koľko položiek máme načítať. Pri každom opakovaní cyklu načítame jednu položku (položku označme ako premennú a) a jej hodnotu pripočítame k výslednej sume. Ďalším algoritmickým problémom je zabezpečiť, aby sa tento cyklus vykonával presne pocet krát. Tu využijeme prvý vstupný údaj pocet. Pri každej iterácii (opakovaní) cyklu sa hodnota premennej pocet zníži o 1. Cyklus budeme opakovať dovtedy, pokiaľ bude premenná pocet rôzna od nuly. Na výpočet súčtu všetkých položiek využijeme premennú suma, ktorú na začiatku vynulujeme (priradíme jej hodnotu 0).


84 2 alg4.png


Násobenie

Zadanie
V počítačoch (na hardvérovej úrovni) sa operácia násobenia vykoná pomocou opakovaného sčítavania dvoch hodnôt. Vytvorte algoritmus, ktorý by násobil dve celé čísla pomocou opakovaného sčítavania.
Analýza problému
Na riešenie problému nemôžeme použiť operáciu násobenia (*), musíme použiť operáciu sčítavania (+). Zoberme si príklad: x=5*3. Tu budeme 3 krát pripočítame hodnotu 5 do premennej x, ktorú musíme najskôr vynulovať. Teda x=5+5+5=15. Vo všeobecnosti máme x=a*b=a+a+...+a : sčítavanie robíme b krát. Z uvedeného vyplýva, že nemôžeme pevne napísať, koľkokrát sa a pripočíta do premennej x. Tu bude vhodné využiť nejaký cyklus. V každom cykle sa do premennej x pripočíta hodnota a. Počet opakovaní cyklu je b. V každej iterácii cyklu hodnotu premennej b znížime o 1. Cyklus ukončíme, ak sa b=0.


86 2 alg5.png

Prvočíslo

Zadanie
Navrhnite algoritmus, ktorý zistí, či zadané číslo a je prvočíslo.
Analýza problému
Prvočíslo je číslo, ktoré je delitelné iba číslom 1 a sebou samým. Pri testovaní čísla a na prvočíselnosť postupne celočíselne deliť číslo a číslami del=2, 3, ...n. Ak pri všetkých deleniach bude nejaký zvyšok (a sa nedá deliť číslom del), povieme že číslo a je prvočíslo. Ak v priebehu delenia zistíme, že a je delitené číslom del bezo zvyšku, algoritmus ukončíme, a povieme že a nie je prvočíslo. Ďalší problém je určiť, dokedy má zmysel zväčšovať deliteľ del. V predchádzajúcom texte sme del zvyšovali po hodnotu n. Úlohou je odhadnúť vhodné n. Pokúsme sa postupovať nasledovne: ako prvý deliteľ je del=2. Teda delíme a číslom del=2. Výsledok po tomto delení označme podiel. Ak budeme premennú del zvyšovať, nebude mať zmysel zväčšovať ju nad hodnotu podiel=a/2, pretože číslo a nemôže deliť žiadne číslo, ktoré je väčšie ako a/2. Ďalej, nech del=3. Ak číslo del (del=3) nedelí číslo a, hranica delenia – n sa zníži na hodnotu a/3, pretože žiadne číslo väčšie ako a/3 nemôže deliť a bezo zvyšku. Z uvedeného nám vyplýva, že hranicu n môžeme určiť nasledovne: Pri každom delení si zapamätáme podiel. Ďalšie delenie robíme iba ak podiel>del. V algoritme použijeme ešte jednu premennú prvocislo. Táto premenná nám bude hovoriť, či je číslo prvočíslo alebo nie je. Na začiatku má hodnotu 1 – teda predpokladáme, že číslo je prvočíslo. V prípade, ak počas delenia zistíme, že nejaké číslo del delí a bezo zvyšku, premennej prvocislo priradíme hodnotu 0. Vyhlásime, že a nie je prvočíslo.
Ukážka
  • a=23
  • a del podiel
  • 23 / 2 = 11 zv 1
  • 23 / 3 = 7 zv 2
  • 23 / 4 = 5 zv 3
  • 23 / 5 = 4 zv 3 del > podiel; koniec; a je prvočíslo, pretože ani jeden zvyšok po delení nebol 0
  • 23 je prvočíslo.


88 2 alg6.png