+ All Categories
Home > Documents > 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF...

1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF...

Date post: 30-Aug-2018
Category:
Upload: vannhu
View: 234 times
Download: 0 times
Share this document with a friend
79
1. Úvod, Algoritmus a jeho charakteristiky Cíl Naučit se řešit problémy s pomocí prostředků výpočetní techniky – jako výpočetní technika Pochopit do hloubky co se dá od těchto prostředků očekávat Naučit se myslet určitým způsobem – jiným než jsou třeba postupy v matematice – zpětné hlubší pochopení určitých problémů Naučit se základům řemesla Naučit se dá všechno, ale chce to systematickou práci a trpělivost Jazyk a prostředí Programovat se dá naučit bez počítače, ale zábavnější je to s ním. Pro psaní programů používáme programovací jazyk. Na jazyce tak moc nezáleží (Je to podobné jako s řízením auta. Naučíte-li se formulovat algoritmy v jednom jazyce stejného typu, není tak těžké přejít na jiný) strukturované, které zahrnují práci s objekty – C++, Object Pascal , VBA, PHP plně objektové jako JAVA, které se pro začátek moc nehodí a bez zvládnutí strukturovaného programování se neobejdou (obojí je podobné, dá se mezi tím přecházet) funkcionální jako Prolog nebo Lisp – jiný způsob myšlení Abychom mohli program napsat, potřebujeme také textový editor, nějaký ladicí prostředek, v současnosti se používá vizuální návrh programů, kde standardní komponenty Windows, jako jsou všelijaká tlačítka a toolbary nemusíme pracně graficky vytvářet, ale jsou k dispozici – to všechno tvoří integrované prostředí. (Borland C++, Borland Delphi, Visual Basic,…) Proč právě Delphi Jazykem Delphi je Object Pascal, který vychází z původního Pascalu profesoraWirtha, navrženého jako jazyk k výuce programování. Delpho přitom poskytují všechny vymoženosti moderního programování (vizuální návrh rozhraní, třídy, výjímky…) a jsou světovými vývojáři považovány za jedno z nejlepších prostředí. Algoritmus a jeho charakteristiky Algoritmická úloha a její specifikace: Jsou dány vstupní údaje vyhovující vstupním podmínkám a výstupní údaje splňující výstupní podmínky. Vytvoř algoritmus – tj. napiš postup, který pro všechny údaje vyhovující vstupním podmínkám získá výstupní údaje vyhovující výstupním podmínkám. Příklad 1: Vejce na tvrdo. Přepokládáme, že existují tři druhy vajec: malá, střední a velká Vstup: Vejce syrové, čerstvé Výstup: Vejce na tvrdo uvařené, jedlé Postup: Dáme vařit vodu. Když se voda vaří (bublá), vložíme vejce. V případě, • že je je vejce malé, nastavíme kuchyňský budík na 1 minutu. • že je je vejce střední, nastavíme kuchyňský budík na 5 minut. • že je je vejce velké, nastavíme kuchyňský budík na 8 minut. Dokud budík nezazvoní, vejce vaříme. Když budík zazvoní, vejce vyjmeme a opláchneme studenou vodou. Příklad 2: řešení lineární rovnice v oboru reálných čísel (ax =b) Vstup a,b reálná čísla Výstup podle a, b buď kořen rovnice nebo oznámení, že daná rovnice má nekonečně mnoho řešení nebo nemá řešení. Postup: Zjistíme a,b Když a není nula, potom můžeme vypočítat kořen x = b/a, řešení je x Jinak když b=0 potom je řešení libovolné reálné číslo PDF created with pdfFactory trial version www.pdffactory.com
Transcript
Page 1: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

1. Úvod, Algoritmus a jeho charakteristiky

Cíl • Naučit se řešit problémy s pomocí prostředků výpočetní techniky – jako výpočetní technika • Pochopit do hloubky co se dá od těchto prostředků očekávat • Naučit se myslet určitým způsobem – jiným než jsou třeba postupy v matematice – zpětné hlubší pochopení

určitých problémů • Naučit se základům řemesla Naučit se dá všechno, ale chce to systematickou práci a trpělivost

Jazyk a prostředí Programovat se dá naučit bez počítače, ale zábavnější je to s ním. Pro psaní programů používáme programovací jazyk. Na jazyce tak moc nezáleží (Je to podobné jako s řízením auta. Naučíte-li se formulovat algoritmy v jednom jazyce stejného typu, není tak těžké přejít na jiný) • strukturované, které zahrnují práci s objekty – C++, Object Pascal , VBA, PHP • plně objektové jako JAVA, které se pro začátek moc nehodí a bez zvládnutí strukturovaného programování

se neobejdou (obojí je podobné, dá se mezi tím přecházet) • funkcionální jako Prolog nebo Lisp – jiný způsob myšlení Abychom mohli program napsat, potřebujeme také textový editor, nějaký ladicí prostředek, v současnosti se používá vizuální návrh programů, kde standardní komponenty Windows, jako jsou všelijaká tlačítka a toolbary nemusíme pracně graficky vytvářet, ale jsou k dispozici – to všechno tvoří integrované prostředí. (Borland C++, Borland Delphi, Visual Basic,…)

Proč právě Delphi Jazykem Delphi je Object Pascal, který vychází z původního Pascalu profesoraWirtha, navrženého jako jazyk k výuce programování. Delpho přitom poskytují všechny vymoženosti moderního programování (vizuální návrh rozhraní, třídy, výjímky…) a jsou světovými vývojáři považovány za jedno z nejlepších prostředí.

Algoritmus a jeho charakteristiky Algoritmická úloha a její specifikace: Jsou dány vstupní údaje vyhovující vstupním podmínkám a výstupní údaje splňující výstupní podmínky. Vytvoř algoritmus – tj. napiš postup, který pro všechny údaje vyhovující vstupním podmínkám získá výstupní údaje vyhovující výstupním podmínkám. Příklad 1: Vejce na tvrdo. Přepokládáme, že existují tři druhy vajec: malá, střední a velká • Vstup: Vejce syrové, čerstvé • Výstup: Vejce na tvrdo uvařené, jedlé Postup: • Dáme vařit vodu. • Když se voda vaří (bublá), vložíme vejce. • V případě, • že je je vejce malé, nastavíme kuchyňský budík na 1 minutu.

• že je je vejce střední, nastavíme kuchyňský budík na 5 minut. • že je je vejce velké, nastavíme kuchyňský budík na 8 minut.

• Dokud budík nezazvoní, vejce vaříme. • Když budík zazvoní, vejce vyjmeme a opláchneme studenou vodou. Příklad 2: řešení lineární rovnice v oboru reálných čísel (ax =b) • Vstup a,b reálná čísla • Výstup podle a, b buď kořen rovnice nebo oznámení, že daná rovnice má nekonečně mnoho řešení nebo

nemá řešení. Postup: • Zjistíme a,b • Když a není nula, potom můžeme vypočítat kořen x = b/a, řešení je x • Jinak když b=0 potom je řešení libovolné reálné číslo

PDF created with pdfFactory trial version www.pdffactory.com

Page 2: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

• Jinak řešení neexistuje • Vypíšeme zprávu o výsledcích

Vlastnosti algoritmu: • Přesnost a elementárnost: algoritmus musí být formulován vzhledem k procesoru, který podle něj bude

pracovat, tj. jazykem, kterému procesor rozumí a pomocí akcí, které umí vykonávat. • Hromadnost – řeší dost velkou třídu úloh (ne jednu rovnici s konkrétními čísly, ale celou skupinu rovnic –

vzpomínáte si na rovnice s parametry?) • Rezultativnost a konečnost – po určitém počtu kroků musí skončit • Determinovanost – pro tentýž vstup musí algoritmus poskytovat týž výstup. (V každém kroku je zřejmé, co

bude následovat.)

Zápisy algoritmů • V přirozeném jazyce – nešikovné, nepřehledné • Graficky – vývojové diagramy, struktogramy – přehledné, ale někdy zbytečně pracné • V programovacím jazyce – pokud si zvykneme na přehledný zápis, nejobvyklejší Program je zápis algoritmu v programovacím jazyce. Tyto jazyky jsou odvozeny z jazyka přirozeného (většinou angličtiny), ale mají jednoznačnou a jednoduchou gramatiku. Aby procesor podle programu mohl pracovat, potřebuje překladač, který překládá z programovacího jazyka do instrukcí strojového kódu. (Ve skutečnosti složitější) Kompilátory – přeloží celý program najednou (rychlejší) Interprety – překládají po příkazech (Interpretovány bývají příkazy OS) Zásady tvorby algoritmů: • Důkladná analýza problému • Algoritmický problém nemusí mít vždy řešení (A je to dobře, protože jinak by nás počítače brzy k ničemu

nepotřebovaly) • Studium literatury • Metoda shora dolů

• Rozklad problému na podproblémy • Zpracování částí • Jejich složení do původního problému

• Zápis v programovacím jazyce • Ladění • Dokumentace

Cvičení Vyzkoušejte si několik příkladů z přijímacích zkoušek na Informatiku na matematicko-fyzikální fakultě v Praze. 1. V algebrogramu nahraďte písmena číslicemi, aby platila rovnost v řádcích i sloupcích. Každé písmeno nahraďte jednou číslicí, různým písmenům odpovídají různé číslice. Uveďte postup úvah, který vede k řešení. (Najděte všechna řešení) A + B = BC – – – D + B = E E + C = E 2. Obdélníková tabulka čokoláda má velikost m*n dílků. Tabulku chceme rozlámat na jednotlivé dílky. Každý zlom musí být rovný a rozlomíme jím jen jeden kus čokolády. Jaký nejmenší počet zlomů potřebujeme? Zdůvodněte. 3. Máme devět na pohled stejných kuliček a víme, že osm z nich je stejně těžkých, zatímco jedna je těžší než ostatní. Navrhněte postup, jak na rovnoramenných vahách naleznete tuto kuličku s nejmenším počtem vážení. Zdůvodněte. 4. Je dána posloupnost cifer 1 2 3 4 5 6 7 8 9 .

PDF created with pdfFactory trial version www.pdffactory.com

Page 3: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Před každou cifru vložte znaménko plus nebo mínus, aby výsledný aritmetický výraz měl hodnotu 33. Nalezněte všechna řešení a vysvětlete, proč další řešení neexistuje. 5. V pytli je B bílých a C černých kuliček. Postupně opakujte následující tahy: Sáhnete do pytle a vytáhnete dvě kuličky. Jsou-li obě bílé, jednu vrátíte zpět. Pokud jste vytáhli jednu bílou a jednu černou, vrátíte do pytle černou. jestliže jste vytáhli dvě černé, dáte do pytle místo nich jednu bílou. Předpokládáme, že máte k dispozici neomezené množství bílých kuliček. Každým tahem se tedy počet kuliček v pytli sníží o 1. Skončíme, když v pytli zůstává poslední kulička. Je možné určit z počátečních hodnot B,C jednoznačně barvu poslední kuličky nebo záleží na pořadí tahů? 6. Ve dvojkovém zápisu čísla jsme některé cifry nahradili písmeny: 1a1b1c010d Zjistěte hodnoty cifer a, b, c, d, jestliže víte, že číslo je dělitelné 6. Určete všechna řešení. 7. Na hromádce je N zápalek. 2 hráči střídavě odebírají zápalky. V jednom tahu může hráč odebrat 1,2,4 nebo 5 zápalek. Vyhraje ten, kdo odebere poslední zápalku. a) Určete, pro jaké hodnoty N má zajištěnou výhru ten, kdo je právě na tahu. b) Jak má postupovat, aby vyhrál. 8. Na stole leží tři zavřené krabice s ovocem. Každá krabice má popsané víko, aby bylo jasné, co je uvnitř. Krabice označená jako JJ obsahuje dvě jablka, HH dvě hrušky, HJ hrušku a jablko. 9. Jestliže v přirozeném čtyřciferném čísle zvětšíme dvě číslice o 3 a zbývající dvě číslice zmenšíme o 4, dostaneme dvakrát větší čtyřciferné číslo. Nalezněte všechna řešení. Řešení 1. C je zřejmě 0, aby fungoval součet jednociferných čísel, musí být B 1. Pak A je 9, 10=2E, tedy E je 5 a D je 4. 9+1=10 - - - 4+1= 5 5+0= 5 2. Každým zlomem se počet kusů zvýší o 1. Na začátku je jeden kus, po kompletním rozlámání n*m kusů. Proto potřebujeme n*m-1 zlomů, na jejich pořadí nezáleží. 3. Kuličky rozdělíme na tři trojice, dvě trojice porovnáme. Buď je trojice obsahující nejtěžší kuličku jedna z nich, nebo ta třetí. (První vážení) Z vítězné trojice vezmeme dvě kuličky a porovnáme.dtto (Druhé vážení) 4. Součet čísel je 45. Má-li být výsledek o 12 menší, musí součet čísel, před kterým je mínus dát 6.. Možnosti: 1,2,3, 2,4, 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a černé kuličky Vytažením dvou bílých kuliček ubyde jedna bílá, počet černých se nezmění. Vytažení černé a bílé ubyde bílá, počet černých se nezmění. Vytažením dvou černých přibyde bílá, ubydou dvě černé. Protože černé kuličky mohou ubývat jen po dvou, byl-ĺi jejich počet původně sudý, nemohou zbýt a poslední kulička je tedy bílá. Pokud byl počet černých kuliček původně lichý, zbyde černá kulička. Zápalky Pozice ve hře je dána počtem zápalek na hromádce. Pozici nazveme vyhranou, může-li si hráč na tahu vynutit výhru. Pozice, které nejsou vyhrané, nazveme prohrané. Prohrané jsou právě ty pozice, kdy je počet zápalek dělitelný třemi. Důkaz: 1. Je-li na hromádce 0 zápalek, hráč na tahu prohrál. 2. Z libovolné pozice, v níž je zápalek dělitelný třemi, se libovolným povoleným tahem dostáváme do pozice,

v níž počet zápalek není dělitelný třemi. 3. Z libovolné pozice, kdy počet zápalek na hromádce není dělitelný třemi. Stačí odebrat tolik zápalek, kolik je

zbytek počtu ve výchozí pozici o dělení třemi.

PDF created with pdfFactory trial version www.pdffactory.com

Page 4: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Ovoce Majitel musí sáhnout do krabice s víkem HJ. Vytáhne-li hrušku, jsou v krabici dvě hrušky, v krabici JJ tedy musí být hruška a jablko a v krabici HH dvě jablka. Analogicky, vytáhne-li jablko, jsou v krabici dvě jablka, v krabici HH tedy musí být hruška a jablko a v krabici JJ dvě hrušky. Dvojková soustava Aby číslo bylo dělitelné 2, d = 0. Pak potřebujeme, aby bylo dělitelné třemi. Převedeme do desítkové soustavy: 676 + 256 a + 64 b + 16 c Každé z čísel 676, 256, 64 a 16 dává při dělení třemi zbytek 1, proto dvě z cifer a,b,c mohou být rovny 1 a třetí musí být nula. Takže úloha má tři řešení. a=1 b=1 c=0 d=0 a=1 b=0 c=1 d=0 a=0 b=1 c=1 d=0 Přirozené čtyřciferné číslo Hledané číslo označíme x. Aby se x zvětšilo, musíme zvětšit první cifru. 1. Zvětšíme 1. a 2. cifru. x se zvětší o 3300 a zmenší o 44. x + 3300 –44 =2x x=3256 2. Zvětšíme 1. a 3. cifru. x + 3030 – 404 = 2x x=2626 4. Zvětšíme 1. a 4. cifru. x + 3003 – 440 = 2x x=2563

2. Dephi – úvod do prostředí, Object Pascal – úvod do syntaxe

Object Pascal Kdybyste si chtěli vytvořit nový jazyk, potřebujete abecedu, na lexikální úrovni slovník a syntaxi – pravidla, jak ze slov vytvářet věty. V našem kurzu nebudeme podrobně popisovat jazyk Object Pascal, ve kterém budeme programovat, detaily si můžete najít v nápovědě Delphi. (viz dále) Abeceda • Písmena latinské abecedy bez „nabodeníček“ • Číslice desítkové a šestnáctkové soustavy (0 až 9, A až F) • Speciální symboly: operátory, závorky, vyhrazená slova Vyhrazená (klíčová) slova Nemohou být změněna, jejich význam je předem dán. Příklady: and, array, …if, ….while, ……with, xor Při psaní kódu editor vyhrazená slova píše obvykle odlišně. Lexikální jednotky • Identifikátory • Čísla • Návěští • Řetězce • Komentáře V programu se oddělují mezerami, oddělovačem řádků, komentáři. Identifikátor Je pojmenování nejrůznějších objektů (proměnných, procedur, programů…). Tvoří ho posloupnost písmen a číslic, nemůže obsahovat mezeru (U víceslovných jmen můžeme jako oddělovač použít podtržítko nebo velká první písmena) a může být libovolně dlouhý, prvních 255 znaků je významných pro rozlišení. Tak dlouhé názvy

PDF created with pdfFactory trial version www.pdffactory.com

Page 5: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

nejspíš používat nebudete, ale měte na paměti, že vhodné pojmenování objketu snižuje čitelnost a přehlednost programu. Příklady: A1, Pole_cisel, PrvniMaximum Číslo Je číselná konstanta, rozlišujeme reálná čísla a celá čísla. (Jinak se ukládají v paměti počítače a umožňují některé odlišné operace) Šestnáctková čísla začínají znakem $. Čísla mohou mít znaménko, reálná čísla se zapisují buď v desetinném tvaru s tečkou nebo ve vědecké notaci. (viz. Excel) Příklady: 45, -2500, 3.1458 Vědecká notace: 12* 1010 zapíšeme jako 12 E 10 4,2*10-5 zapíšeme 4.2E-5 Některé operace s celými čísly +, - , * , div – operátor celočíselného dělení (45 div 10=4), mod – operátor zbytku po celočíselném dělení: (45 mod 10 = 5) Některé operace s reálnými čísly +, - ,* /, Některé funkce: Sqr(x) x2 pro celé číslo x je výsledek celé číslo, pro reálné čísolo reálné. Sqrt(x) √x výsledek vždy reálné číslo Abs(x) |x| pro celé číslo x je výsledek celé číslo, pro reálné čísolo reálné. Sin(x), cos(x) výsledek vždy reálné číslo, sinx,cosx Trunc(x) výsledek celé číslo – celá část čísla (Trunc(3.9)=3) Round(x) zaokrouhlení, výsledek celé číslo Pi konstanta – Ludolfovo číslo Výrazy Priorita operátorů je podobná jako v matematice, stejně jako v Excelu se používají pouze kulaté závorky, které lze vnořovat. Řetězce Jsou posloupnosti 0 až více znaků rozšířeného kódu ASCII, uzavřených mezi dvěma apostrofy. Apostrofy uvnitř řetězce je třeba zdvojit. Příklady: ‘Mám hlad.’ ‘You’’ll come’ Kontrolní znaky se vkládají pomocí # a čísla ASCII kódu. (#13 – oddělovač řádků) Délkou řetězce je počet znaků. Řetězce můžeme spojovat znaménkem +. (‘3’+’4’=’34’) Prázdný řetězec jsou dva apostrofy vedle sebe. Komentáře Jsou překladačem ignorovány a slouží především k lepší čitelnosti programu. Víceřádkové se vkládají do složených závorek nebo závorek s hvězdičkami, jednořádkové mohou začínat dvěma lomítky. Příklady: {Jakýkoli text, který neobasahuje pravou složenou závorku ****************************************************} (*Jakýkoli text, který neobasahuje pravou složenou závorku *************************************************** *) // jakýkoli text do konce řádku Programový celek Může být program, podprogram (procedura, funkce), programová jednotka (unit), projekt. Struktura je vždy podobná: Hlavička s identifikátorem; Deklarační část; Begin Příkazová část End.

PDF created with pdfFactory trial version www.pdffactory.com

Page 6: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Delphi Slouží k rychlému a snadnému vývoji aplikací pro Windows. Poskytuje vizuální, objektově orientované a komponentově založené prostředí pro tvorbu programů (včetně databázových a webových aplikací, DLL knihoven apod.) Vizuální Uživatelské rozhraní svých programů můžeme vytvářet pouhým přetažením objektů (tlačítek, rozvíracích roletek, editačních políček…) na formulář. Objektově orientované Budeme nejen programovat vlastní třídy, ale také s využitím dědičnosti upravovat komponenty Delphi a vytvářet komponenty vlastní. Komponenty Uživatel má k dispozici knihovnu vizuálních komponent, běžně užívaných ve Windows, kterou může navíc rozšiřovat a upravovat.

IDE Integrated development environment – je integrované vývojové prostředí, díky kterému můžeme užívat všechno, co Delphi nabízejí. Při prvním spuštění programu se otevře okno programu s formulářem připraveným pro novou aplikaci. Shora: Hlavní nabídka Vlevo – panel nástrojů pro často užívané příkazy, vpravo – paleta komponent (vše uživatelsky konfigurovatelné) Vlevo – inspektor objektů , vpravo navrhář formuláře a editor kódu. V novějších verzích Delphi bývají další okna. (Project Manager. Object Tree View…) Inspektor objektů Obsahuje dvě záložky – Properties (vlastnosti) a Events(události), jejichž pomocí nastavujeme vlastnosti komponent (například rozměry tlačítka) a programujeme události. (Co se stane, když klikneme na tlačítko) Některé vlastnosti v době návrhu můžeme měnit myší (rozměry), jiné přímo zápisem. Dají se také měnit za běhu programu, to je ovšem nutné naprogramovat.

PDF created with pdfFactory trial version www.pdffactory.com

Page 7: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Ahoj, lidi – návod k vytvoření první aplikace 1. File/New Application (nebo první spuštění Delphi) vygeneruje nový formulář s příslušným kódem. 2. V Inspektoru objektů (OI) klepneme do okénka Caption (popisek) a napíšeme jméno formuláře – Pozdrav. 3. File/Save All – připravíme složku, do které postupně uložíme soubor Project1 pod jménem Pozdrav.dpr a

Unit1 pod jménem Pozdrav1.pas. (Delphi do této složky uloží ještě další soubory, o jejich významu, o struktuře unitu i projektového souboru si povíme časem) Je dobré volit vhodné názvy, abychom se v projektu orientovali. Také si v souborech udržíme lepší přehled, když každou aplikaci (celý projekt se šemi jeho soubory) uložíme do zvláštní složky.

4. Tažením myší umístíme na formulář tlačítko (OK). 5. V OI nastavíme Caption tlačítka na Řekni ahoj. 6. Poklepeme na tlačítko (Nebo na záložce Events zaklepeme do okénka OnClick¨) a Delphi vygenerují

proceduru, do jejíhož kódu se přesuneme. 7. Zapíšeme následující kód: showmessage (‘Ahoj, lidi!!!’);

Takže to bude vypadat takhle:

8. Projekt spustíme zelenou šipkou na nástrojové liště nebo Run/Run – přitom se nejprve přeloží, pokud jsme

spáchali nějaké syntaktické chyby (v zápise programu), upozorní nás na ně. Showmessage Je procedura, která zobrazí okno se správou. Tato správa je řetězec, který v programu zapíšeme do závorek jako její parametr. (viz výše). Zatím tuto proceduru budeme používat pro výstup programů. Protože umí zobrazit pouze řetězec a my budeme chtít provádět také výpočty, seznámíme se s převodními funkcemi: IntToStr (číslo) – převede celé číslo na řetězec FloatToStr (číslo) – převede reálné číslo na řetězec. Příklady: Showmessage(floattostr(sqr(2)) – zobrazí odmocninu ze dvou Showmessage(‘Jméno:’ +’#13’+’Příjmení’) – výpis na dva řádky (+ spojí dva texty dohromady a #13 oodpovídá odřádkování) Showmessage(Button1.caption) – zobrazí správu s názvem tlačítka Některé vlastnosti komponent Caption – popisek Color – barva (poklepnáním na barvu se spouští Colordialog, známý např. z Malování, když si mícháte vlastní barvy) Font – font (klepnutím na tlačítko s třemi tečkami vlevo se otevře typický FontDialog, kde se dají nastavit různé vlastnosti písma Height – výška Hint – text bublinkové nápovědy (Zobrazuje se, je-li nastaveno ShowHint na True) Left – vzdálenost levého horního rohu od levého okraje nadřazeného prvku (pro formulář obrazovka)

PDF created with pdfFactory trial version www.pdffactory.com

Page 8: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Name – identifikátor (nemění se když změníme caption, naopak ano) Top – vzdálenost levého horního rohu od horního okraje nadřazeného prvku (pro formulář obrazovka) Width – šířka Práce s vlastnostmi komponent za běhu programu: JménoKomponenty.vlastnost Příklady: Form1.caption – popisek formuláře Showmessage(‘Tlačítko se jmenuje ‘+ button1.caption) Nápověda Help – volíme položku z obsahu, nebo zapíšeme vyhledávaný objekt v rejstříku. Pokud nastavíme kurzor na rezervované slovo v kódu a stiskneme F1, dostaneme nápovědu o jazyce. V Object inspektoru podobně získáme nápovědu o vlastnostech komponenty. Klávesové zkratky F1 – help F9 – spuštění programu F12 – přepíná mezi formulářem a editorem kódu F11 – zobrazení inspektora objektů (OI)

Cvičení Každý projekt uložte do zvláštní složky. 1. První projekt – tlačítka Vložte na formulář tři tlačítka a pojmenujte je lidskými jmény. Při klepnutí na libovolné z nich by se měla objevit zpráva: Zdraví tě a název tlačítka. Připojte čtvrté tlačítko, které změní popisek formuláře na jména všech tří tlačítek za sebou, oddělená čárkami..´ 2. Druhý projekt – počty Zobrazte výslednou hodnotu výrazů: (Každou jako reakci na stisknutí tlačítka) Cílem je naučit se s výrazy pracovat, výsledky si kontrolujte ručně)

1. 610400

2.

43111+

3. celá část (2*π*100) 4. Zbytek po celočíselném dělení 100: 3 Třetí projekt. Po stisknutí tlačítka se zobrazí zpráva s více řádky.

Řešení 1. … procedure TForm1.Button3Click(Sender: TObject); begin showmessage('Ahoj '+button3.caption); end; procedure TForm1.Button4Click(Sender: TObject); begin form1.caption:=button1.Caption+', '+button2.Caption+', '+button3.Caption; end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 9: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

procedure TForm1.Button1Click(Sender: TObject); begin Showmessage( FloatToStr(sqrt(400/1E-6))) end; procedure TForm1.Button2Click(Sender: TObject); begin Showmessage( FloatToStr((1+11)/(3/4))) end; procedure TForm1.Button3Click(Sender: TObject); begin Showmessage( IntToStr(trunc(2*pi*100))) end; procedure TForm1.Button4Click(Sender: TObject); begin Showmessage( IntToStr(100 mod 3)) end; 3. – viz příklad v textu

3. Proměnná a její deklarace, přiřazovací příkaz

Proměnná a její deklarace Jako v matematice, i v programování budeme potřebovat pracovat s proměnnou, tedy s objektem, jehož hodnota není konstantní, ale může se měnit. Proměnnou si představujeme jako symbolické označení místa v paměti počítače, kde je uložena její hodnota. Každá proměnná má přiřazen identifikátor – jméno. Jestliže budeme pracovat s proměnnou, která obsahuje číslo, bude zabírat jinak velký úsek paměti a budeme s ní moci provádět jiné akce, než například s řetězcem, je tedy zřejmé, že každá proměnná musí být určitého typu. (V Delphi sice existuje typ variant, do něhož se vejde cokoliv, ale jeho používání je nehospodárné vzhledem k paměti a navíc zdržuje dobu výpočtu) Identifikátor a typ proměnné specifikujeme v deklarační části programu. Var x,z: Real; x, z budou reálné proměnné, budeme pro ně tedy např. moci používat operátor /. Index: Integer; celočíselná proměnná Jmeno: String; proměnná typu řetězec S deklarací je dán nejen typ proměnné (a tedy jakých hodnot může nabývat a co s ním můžeme dělat), ale také programový celek (procedura, unit…), kde se s proměnnou dá pracovat.

Přiřazovací příkaz Příkazové konstrukce zapisujeme do příkazové části programu – mezi begin a end a oddělujeme je středníky. Hodnotu proměnné můžeme měnit buď načtením (dále) nebo pomocí příkazu přiřazení. V Delphi má tvar Proměnná := výraz; (:= je operátor přiřazení) Nejprve se vyhodnotí výraz na pravé straně, pak se získaná hodnota uloží do proměnné nalevo. Zřejmě výraz musí být stejného typu jako proměnná. (Výjimkou je celočíselná hodnota, kterou můžeme přiřadit do reálné proměnné) Příklady (s výše deklarovanými proměnnými) x:=2*pi; Index:=20; Index:=Trunc(x); (Index bude mít hodnotu 6) Index:=Index+1; (Index bude mít hodnotu 7, tímto příkazem zvětšíme jeho hodnotu o jedničku) Jmeno:=‘BAF‘; Jmeno:=Jmeno+IntToStr(Index); (Jmeno bude mít hodnotu ‘BAF7‘)

PDF created with pdfFactory trial version www.pdffactory.com

Page 10: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Editační políčko, Edit Nejdůležitější vlastností všech komponent je jejich identifikátor, vlastnost Name. Abychom mohli zajistit také vstup našich programů, budeme (zatím) potřebovat další komponentu, známou z Windows – editační políčko. (Edit). Nalezneme ji jako čtvrtou na paletě komponent Standard a umístíme na formulář podobně, jako tlačítko. V inspektoru objektů si povšimneme kromě některých známých vlastností (width, height, name) vlastnosti Text, která obsahuje text zapsaný do políčka a je typu řetězec. Jestliže se políčko jmenuje Edit1, k jeho textu se dostaneme pomocí tečkované notace – Edit1.text. (Pokud ho přejmenujeme – name – třeba na Vstup, bude to Vstup.text) Příklad 1. – varianta pozdravu. Na formulář umístíme komponenty Edit a Button. Name Editu nastavíme na Vstup, name tlačítka na Akce. Do události Form1.AkceClick zapíšeme kód: procedure TForm1.AkceClick(Sender: TObject); {Pozdravna procedura} var pozdrav:string; begin pozdrav:='Zdraví tě '+ Vstup.Text; showmessage(pozdrav); Vstup.clear; end; Poznámky: • Jako komentář obvykle zapisujeme potřebné informace o programu • Komponenty mají kromě událostí také metody – metoda editačního políčka Clear políčko vyprázdní. Volá

se rovněž s tečkovanou notací. • Všimněte si, že jako argument příkazu Showmessage vystupuje proměnná pozdrav, která obsahuje řetězec,

nikoliv řetězcová konstanta v apostrofech. • Do této události tlačítka se dostaneme také poklepáním na tlačítko, protože je to událost pro tuto

komponentu implicitní. Příklad 2. Měli bychom vypočítat obsah kruhu a délku kružnice, ze zadaného poloměru. Abychom mohli užít editační políčko ke vstupu čísel, potřebujeme konverzní funkce, které převedou řetězec na reálné (StrToFloat(x)) nebo celé číslo. (StrToInt(x)) StrToInt(‘34’) převede řetězec na celé číslo 34 StrToFloat(‘3.14‘) převede řetězec na reálné číslo 3.14. procedure TForm1.Button1Click(Sender: TObject); {vstup: polomer, vystup obvod a obsah, vse realna cisla} var r,O,S:real; begin r:=StrToFloat(Edit1.text); {Nacteni vstupu, prirazeni realneho cisla do polomeru} O:=2*pi*r; S:=pi*sqr(r); {vypocty} Showmessage('S= '+FloatTostr(S)); Showmessage('O= '+FloatTostr(O)); {zobrazeni vysledku} end; Priklad 3. Na vstupu jsou odvěsny pravoúhlého trojúhelnika, chceme vypočítat jeho obsah a obvod. procedure TForm1.Button1Click(Sender: TObject); {vstup: a,b, vystup obvod a obsah, vse realna cisla} var a,b,c,O,S:real; begin a:=StrToFloat(Edit1.text); b:=StrToFloat(Edit2.text); {Nacteni vstupu, prirazeni realneho cisla )

PDF created with pdfFactory trial version www.pdffactory.com

Page 11: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

c:=sqrt(sqr(a)+sqr(b)); O:=a+b+c; S:=a*b/2; {vypocty} Showmessage('S= '+FloatTostr(S)); Showmessage('O= '+FloatTostr(O)); {zobrazeni vysledku} end; Příklad 4. Na vstupu je údaj v milimetrech, chceme ho převést na metry, centimetry a milimetry. (1205mm=1 m 20 cm 5 mm) procedure TForm1.Button1Click(Sender: TObject); {vstup: a,b, vystup obvod a obsah, vse realna cisla} var VstupMm, VystupMm, Cm, M:integer; vysledek:string; {vysledek slouzi k vytvoreni odpovedi pred zobrazenim} begin VstupMm:=StrToInt(Edit1.text); {Nacteni vstupu, prirazeni realneho cisla do polomeru} M:=VstupMm div 1000; VystupMm:= VstupMm mod 1000; {Dale budeme zpracovavat zbyle mm} Cm:= VystupMm div 10; VystupMm:=VystupMm mod 10; {vypocty} vysledek:=IntTostr(VstupMm)+'mm =' +IntToStr(m)+ 'm +' +IntToStr(Cm)+'cm + '+ IntToStr(VystupMm)+'mm'; Showmessage(vysledek); {zobrazeni vysledku} end;

Cvičení Napište programy, které vypočítají pro zadané vstupní hodnoty požadované hodnoty výstupní. 1. Vstup: strany obdélníka, výstup: obvod, obsah, úhlopříčka 2. Vstup: strana krychle, výstup: povrch, objem, tělesová úhlopříčka, stěnová úhlopříčka 3. Vstup: dva odpory, výstup hodnota celkového odporu při paralelním a sériovém zapojení. 4. Vstup: rychlost v metrech za sekundu (reálné číslo), výstup: rychlost v kilometrech za hodinu. 5. Vstup: poloměr a výška válce, výstup: objem a povrch 6. Vstup: údaj v hodinách (celé číslo), výstup: údaj ve dnech a hodinách

Řešení: (Výpisům chybí jednotky, dotáhněte to k dokonalosti sami) 1. var a,b,u,S,o:real; begin a:=StrToFloat(Edit1.Text); b:=StrToFloat(Edit2.Text); o:=2*(a+b); S:=a*b; u:=sqrt(sqr(a)+sqr(b)); showmessage ('S= '+FloatTostr(S)+#13+ 'o= '+FloatTostr(o)+#13+ 'u= '+FloatTostr(u)+#13) end; 2. var a,us,ut,S,V:real; begin a:=StrToFloat(Edit1.Text);

PDF created with pdfFactory trial version www.pdffactory.com

Page 12: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

V:=a*a*a; S:=6*a*a; us:=sqrt(2)*a; ut:=sqrt(3)*a; showmessage ('V= '+FloatTostr(V)+#13+ 's= '+FloatTostr(S)+#13+ 'us= '+FloatTostr(us)+#13+ 'ut= '+FloatTostr(ut)+#13) end; 3. var R1,R2,RS,RP:real; begin R1:=StrToFloat(Edit1.Text); R2:=StrToFloat(Edit2.Text); RS:=R1+R2; RP:=R1*R2/(R1+R2); showmessage ('RS= '+FloatTostr(RS)+#13+ 'RP= '+FloatTostr(RP)+#13) end; 4. var ms,kmh: real; begin ms:=StrToFloat(Edit1.Text); kmh:=ms*3.6; showmessage (FloatToStr(ms)+' m/s = '+FloatTostr(kmh)+'km/h'); end; 5. var r,vy,S,V,podst:real; begin r:=StrToFloat(Edit1.Text); vy:=StrToFloat(Edit2.Text); podst:= pi*sqr(r); S:=podst+2*pi*r*vy; V:=podst*vy; showmessage ('V= '+FloatTostr(V)+#13+ 'S= '+FloatTostr(S)+#13) end; 6. var h,dny: integer; begin h:=StrToInt(Edit1.Text); dny:=h div 24; h:=h mod 24; showmessage ('dny= '+FloatTostr(dny)+#13+ 'hodiny= '+FloatTostr(h)+#13) end;

4. Složený příkaz, deklarace konstanty Někdy budeme potřebovat, aby několik následujících příkazů figurovalo jako celek. (Například vykonalo se za určité podmínky). Potom tuto posloupnost příkazů uzavřeme mezi příkazové závorky – begin a end. Příklad: Výměna obsahu dvou proměnných a, b (Obsah dvou skleniček a,b přelévám přes další prázdnou skleničku pom) Begin Pom:=A; A:=B;

PDF created with pdfFactory trial version www.pdffactory.com

Page 13: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

B:=Pom; End; Poznámka: takto se dá vyměnit obsah proměnných libovolného typu, u čísel si můžeme třetí proměnnou ušetřit: Begin Předpokládejme, že A=3, B=4 A:=A+B; A=7 B:=A -B; B=3 A:=A-B; A=4 End;

Deklarace konstanty Pracujeme-li v programu s konstantami, (např. hmotnost elektronu ), stane se program čitelnějším a rychleji upravitelnějším, když hodnotu nahradíme jejím identifikátorem. Deklarace konstanty se provádí v deklarační části programu a uvádí vyhrazeným slovem const Const Me=9.1E-31; Pozdrav=’Ahoj, můj nejmilejší uživateli’; Pocet=100; Var x:real; n:integer; ….. Begin x:=Me*1000; writeln(Pozdrav); Počet:=Počet+1; End; Také Delphi pracují s konstantami, například při definici barev clRed – červená, clBlue – modrá…)

Komponenta Label Je třetí zleva na (písmenko A) na paletě komponent Standard a využívá se především její vlastnost Caption, která obsahuje řetězec. Používá se jako informační popisek.

Změna vlastností komponent za běhu programu Každá komponenta má identifikátor – Name. Delphi volí identifikátor podle typu komponenty a pořadí, ve kterém byla vložena na formulář. Např. ptro tlačítka Button1, Button2… Pokud jich máme na formuláři více, je vhodné vlastnost Name změnit, abychom se v nich vyznali. Většinou se při pojmenování dodržuje obdobná konvence – VstupEdit, AkceButton apod. Na další vlastnosti komponent se pak odvoláváme pomocí tohoto identifikátoru a jména příslušné vlastnosti. Příklady: Form1.Color – barva formuláře Button1.Caption – popisek tlačítka Button1.width – šířka tlačítka Label1.Caption – text popisku Edit1.Text – text v editačním políčku. Tyto vlastnosti vystupují v programu jako proměnné a jejich hodnoty jde měnit přiřazovacím příkazem: Form1.color:=clRed; Button1.width:=Button1.width+10; (Rozšíří tlačítko o 10 pixelů) Label1.caption:=’Zadejte své jméno:’;

Cvičení: 1. Vstup: počet vrcholů n-úhelníku, výstup – počet úhlopříček 2. Vstup: údaj v hodinách, minutách sekundách, výstup: údaj v sekundách 3. Vstup: údaj v sekundách, výstup: údaj v hodinách, minutách sekundách 4. Vstup: Celé číslo, výstup: jeho poslední cifra 5. Vstup: slova – podmět, přísudek a předmět, výstup – věta sestavená ze slov v tomto pořadí a zakončená

tečkou. Dál používejte deklaraci konstanty pro {χ} =6.67 *10-11 6. Vstup – hmotnosti a vzdálenost dvou těles, výstup – gravitační síla, kterou na sebe tělesa působí 7. Vstup – hmotnost tělesa , výstup gravitační síla, kterou na těleso působí Země na sv0m povrchu.

(Rz = 6378 km, Mz =5,983 *1024 kg – další konstanty) 8. Připravte formulář s několika tlačítky, každé ponese jméno nějaké barvy. Při stisknutí tlačítka se adekvátně

změní barva formuláře.

PDF created with pdfFactory trial version www.pdffactory.com

Page 14: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

9. Připravte formulář s tlačítkem, editačním políčkem a popiskem (Label). Při stisknutí tlačítka se obsah editačního políčka zkopíruje do popisku a editační políčka se vyprázdní.

10. Připravte si formulář s tlačítkem, při každém klepnutí se tlačítko zvětší. (Na všechny strany symetricky)

Řešení: Protože si už s výpisy a dalšími detaily programu poradíte sami, bedeme, pokud to nebude třeba, uvádět jen části kódů. 1. var n,p:integer; begin n:=StrToInt(Edit1.Text); p:=n*(n-3) div 2; ShowMessage(IntToStr(p)); end; 2. var ho,mi,se:integer; … se:=ho*3600+mi*60+se; … 3. var ho,mi,se:integer; begin se:=StrToInt(Edit1.Text); ho:=se div 3600; se:=se mod 3600; mi:=se div 60; se:= se mod 60; ShowMessage(IntToStr(ho)+#13+ IntToStr(mi)+#13+IntToStr(se)); end; 4. … posleda= x mod 10; … 5. var podmet,prisudek,predmet.veta:string; begin podmet:=edit1.text; prisudek:=edit2.text; predmet:=edit3.text; veta:=podmet+’ ‘+prisudek+’ ‘+predmet+’.’ ShowMessage(veta); end; 6. const kapa=6.67E-11; var m1,m2,r,F:real; begin m1:=StrToFloat(edit1.Text); m2:=StrToFloat(edit2.Text); r:=StrToFloat(edit3.Text); f:=kapa*m1*m2/sqr(r); Showmessage(FloatTostr(F)); end; 7. const kapa=6.67E-11; Mz=5.983E24;Rz = 6.378E6; var m,F:real; begin m:=StrToFloat(edit1.Text); f:=kapa*m*Mz/sqr(Rz); Showmessage(FloatTostr(F)); end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 15: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

8. …form1.color:=clred;…{barevne konstanty nejdeme napr. ve vlastnosti color formulare} 9. … label1.caption:= edit1.text; edit1.clear; 10. begin button1.width:=button1.width+10; button1.height:=button1.height+10; button1.left:=button1.left-5; button1.top:=button1.top-5; end;

5. Podmíněné příkazy – if

Neúplný podmíněný příkaz Má tvar: If Podmínka Then Příkaz; Nejprve se vyhodnotí podmínka, je-li pravdivá, provede se příkaz. V opačném případě se nestane nic. Pokud potřebujeme, aby příkaz zahrnoval více akcí, je třeba z nich vytvořit složený příkaz uzavřením mezi klíčová slova begin a end; Příklad: Do dvou editačních políček budeme vkládat čísla, přitom chceme, aby v prvním políčku bylo číslo větší nebo rovné číslu druhému. Kdyby uživatel zadal čísla obráceně, vyměníme je. …. Var Mensi, Vetsi:real; Pom: String; {pro vymenu obsahu policek} Begin Mensi:=StrToFloat(Edit1.text); Vetsi:=StrToFloat(Edit2.text); If mensi>vetsi Then Begin Pom:=Edit1.text; Edit1.text:=Edit2.text; Edit2.text:=Pom; End;

Úplný podmíněný příkaz Má tvar: If podmínka Then Příkaz1 Else Příkaz2; Opět se nejdřív vyhodnotí podmínka, platí-li, provede se příkaz1, jinak se provede příkaz2. Pozor! Za Příkaz1 (tedy před klíčové slovo Else) se nepíše středník. Příklad 1: Vstup – reálné číslo, výstup – převrácená hodnota čísla nebo upozornění na chybné zadání v případě, že uživatel zadá nulu. Kromě upozornění na chybu editační políčko vymažeme a nastavíme do něho kurzor (Tomu se říká předání zaměření – metoda SetFocus) … Var x, Prevrx:real; Begin x:= StrToFloat(Edit1.text); If x<>0 Then Begin PrevrX :=1/x ; Showmessage (FloatToStr(PrevrX));

PDF created with pdfFactory trial version www.pdffactory.com

Page 16: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

End Else Begin Showmessage(‘Prevracena hodnota k nule neexistuje’); Edit1.Clear; Edit1.SetFocus; End; Poznámka: všimněte si způsobu zápisu kódu programu a zvykněte si na dodržování pravidel: Begin a End, které k sobě patří, píšeme pod sebe, podobně Then a Else. Příkazy, které jsou na stejné úrovni vnoření, píšeme pod sebe, příkazy, které jsou vnořeny do jiných, odsazujeme doprava. Pak se ve svých programech budete dobře orientovat. Příklad 2. Řešení lineární rovnice Ax +B = 0 v oboru reálných čísel. procedure TForm1.Button1Click(Sender: TObject); var a,b, x:Real; vysl:String; begin Label3.caption:='Rovnice: '; Label4.caption:='Řešení: '; a:=StrToFloat(Edit1.text); b:=StrToFloat(Edit2.text); Label3.caption:=Label3.caption + Edit1.text+' x + '+ Edit2.text+' = 0'; if a=0 then if b=0 then vysl:='Nekonecne reseni' else vysl:='Reseni neexistuje' else begin x:=-b/a; vysl:='x = '+ FloatToStr(x); End; Label4.caption:= Label4.caption+ vysl; end;

Cvičení: Pro každou úlohu vytvořte nový projekt, co má uživatel zadat specifikujte do příslušných popisků. Nezapomeňte všechny soubory projektu uložit vždy do nové složky. 1. Vstup: dvojice reálných čísel, výstup: převrácená hodnota k jejich součtu 2. Vstup: dvě kladná reálná čísla, strany pravoúhelníka. Výstup: Oznámení, zda se jedná o čtverec nebo

obdélník, údaje o straně (u obdélníka nejprve menší, pak větší strana), obvod, obsah a úhlopříčka pravoúhelníka.

3. Na vstupu jsou čtyři údaje, dráha a čas prvního auta, dráha a čas druhého auta. (V km a h). Vytiskněte, které auto je rychlejší a o kolik

Řešení Příklad 1. ... if x+y=0 then showmessage('nelze') else begin v:=1/(x+y); showmessage(floattostr(v)); end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 17: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Příklad 2. .... if a=b then begin {ctverec} u:=x*sqrt(2); showmessage('ctverec'+#13+ 'strana '+ Edit1.text+#13+ 'uhlopricka' + FloatToStr(u)); end else begin {obdelnik} if a>b then begin v:=a;a:=b;b:=v; end; u:=sqrt(sqr(x)+sqr(y)); showmessage('obdelnik'+#13+ 'mensi strana '+ FloatTostr(a)+#13+ 'vetsi strana '+ FloatTostr(b)+#13+ 'uhlopricka' + FloatToStr(u)); end; Příklad 3. ... v1:=s1/t1; v2:=s2/t2; rozdil:=abs(v1-v2); if v1=v2 then showmessage('rychlost stejna') else begin if v1>v2 then vysl:='Rychlejsi je prvni o ' else vysl:='Rychlejsi je druhe o '; vysl:=vysl+floattostr(rozdil)+' km/h'; showmessage(vysl); end;

6. Podmíněné příkazy – pokračování

Spojení obou typů podmíněných příkazů Pokud za klíčovým slovem then následuje další if, pak je následující konstrukce: If podmínka1 Then If podmínka2 Then příkaz1 Else příkaz2; chápána tak jak je zapsána – tedy: If podmínka1 Then Begin If podmínka2 Then příkaz1 Else příkaz2 End; Pokud potřebujeme, aby se else vztahovalo k prvnímu then, musíme vhodně použít příkazové závorky: If podmínka1

PDF created with pdfFactory trial version www.pdffactory.com

Page 18: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Then Begin If podmínka2 Then příkaz1 End Else příkaz2;

Událost OnKeypress Najdeme v Object Inspectoru například pro komponentu Edit. Má parametr Key typu char (znak – později), Ve kterém je uložena hodnota právě stisknutého znaku v komponentě. Můžeme ji použít například, když potřebujeme ukončit vstup údajů stisknutím klávesy Enter, jejíž ASCII kód je 13, což používáme, dělíme-li výpisy řetězců do více řádků. (Poznámka: Podobná událost editačního políčka t OnKeyDown generuje skutečný kód klávesy (číselný), který není ovlivněn např. volbou klávesnice) Příklad: Do editačního políčka zapíšeme jméno, po stisknutí Enter se objeví pozdrav, políčko se vyprázdní a nastaví se do něj kurzor. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if key=#13 then begin showmessage(‘ Ahoj ‘+Edit1.text); Edit1.clear; Edit1.setfocus; End; end;

Zarovnání komponent na formuláři Potřebujeme-li například zarovnat několik editačních políček pod sebe levými okraji s pravidelným rozmístěním ve svislém směru, můžeme je vybrat s klávesou Shift a použít příkaz Align z místní nabídky. S dialogovým oknem se pracuje podobně jako se zarovnáváním objektů v Corelu. Pokud chceme na formulář umístit více komponent stejného typu, můžeme trvale zamáčknout příslušné tlačítko na paletě komponent rovněž s použitím klávesy Shift. Jeho uvolnění pak provedeme klepnutím na tlačítko se šipkou, kterým paleta komponent začíná. Logické spojky Logické výrazy v podmínkách můžeme jako v matematice spojovat logickými operátory: And – konjunkce (a zároveň, je platná platí-li oba výroky) Or – disjunkce (nebo, je neplatná neplatí-li ani jeden výrok) Pozor na prioritu operátorů – největší mají multiplikativní (násobení, and), pak aditivní a nejmenší relační (<,>...)operátory, takže je třeba používat vhodně závorky: If ((a+b)>c) and ((b+c)>a)…

Složitější příklady na větvení programu Rozbory příkladů budeme formulovat v jakémsi pseudojazyku – s využitím příkazů Object Pascalu a pomocných instrukcí, které pak dále rozpracujeme do jednotlivých příkazů jazyka. 1. Řešení kvadratické rovnice v oboru reálných čísel Rozbor: Kvadratická rovnice je dána reálnými koeficienty a,b,c. Ax2 +Bx +C=0

PDF created with pdfFactory trial version www.pdffactory.com

Page 19: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Podobně jako když v matematice řešíme rovnici s parametry, i zde musíme brát v úvahu všechny možnosti v zadání. If A=0 Then Řešení lineární rovnice Else Begin Výpočet diskriminantu; If diskriminant=0 Then Výpočet dvojnásobného kořenu Else If diskriminant<0 Then Rovnice nemá řešení Else Výpočet dvou reálných kořenů End 2. Nalezení maxima ze tří čísel Rozbor: If a>b Then Porovnáme a,c, větší je maximum Else Porovnáme b,c, větší je maximum 3. Nalezení maxima a minima ze čtyř čísel. Porovnáme první dvě čísla, menší uložíme do minima, větší do maxima. Pak porovnáme druhá dvě čísla, menší s minimem, větší s maximem 4. Vstup: tři kladná čísla. Zjistěte, zda mohou tvořit trojúhelník, jestliže ano, vypočítejte jeho obsah.. Rozbor: If Platí pro čísla trojúhelníkové nerovnosti Then Výpočet podle Heronova vzorce Else Čísla nejsou strany trojúhelníka 5. Vstup dolní, horní mez intervalu a číslo. Vytiskněte, zda číslo náleží otevřenému intervalu. Rozbor: if dolni mez>horni mez, then výměna; of x>=dolni mez a současně x<=horni mez…

Řešení 1. var a, b, c, D, x1,x2:real; if a=0 then {linearni} begin zprava:='Linearni rce:'; if b=0 then if c=0 then zprava:=zprava+'R' else zprava:=zprava+'zadne reseni' else begin x:=c/b; zprava:=zprava+FloatToStr(x); end; end else begin zprava:='Kvadraticka rce:';

PDF created with pdfFactory trial version www.pdffactory.com

Page 20: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

D:=b*b-4*a*c; if D<0 then zprava:=zprava+'zadne reseni' else if D=0 then begin x:=-b/(2*a); zprava:=zprava+'Dvojnasobny koren :'+FloatToStr(x); end else begin zprava:=zprava+'dve reseni'; x1:=(-b+sqrt(D))/(2*a); x2:=(-b-sqrt(D))/(2*a); zprava:=zprava+#13+'Koren 1:'+FloatToStr(x1)+#13+'Koren2:'+FloatToStr(x2); end; end; 2. var a,b,c,max:real; begin … if a>b then if a>c then max:=a else max:=c else if b>c then max:=b else max:=c; … end; 3. var a,b,c,d,max,min:real; begin … if a>b then begin max:=a; min:=b end else begin max:=b; min:=a; end; if c>d then begin if c>max then max:=c; if d<min then min:=d; end else begin if d>max then max:=d; if c<min then min:=c; end; … end; 4. var a,b,c,Opul,S:real; begin…

PDF created with pdfFactory trial version www.pdffactory.com

Page 21: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

{Existenci trojuhelnika overime pomoci trojuhelnikove nerovnosti, obsah vypocitame Heronovym vzorcem} if ((a+b)>c) and ((b+c)>a) and((a+c)>b) then begin showmessage('trojuhelnik'); Opul:=(a+b+c)/2; S:=sqrt((Opul-a)*(Opul-b)*(Opul-c)*Opul); showmessage('Obsah: '+ FloatToStr(S)); end else showmessage('netvori trojuhelnik'); … end; 5. var a,b,x:real; begin a:=StrToFloat(Edit1.text); b:=StrToFloat(Edit2.text); if a>b then begin x:=a;a:=b;b:=x; end; x:=StrToFloat(Edit3.text); if (x>a) and (x<b) then showmessage('je tam') else showmessage('neni tam'); end;

7. Cykly – příkaz while V algoritmech se často vyskytuje situace, kdy je třeba nějaký příkaz zopakovat. Potom používáme příkaz cyklu: while Podmínka do Příkaz; Nejprve se ověří podmínka, pokud platí, provede se příkaz a znovu se ověří podmínka… Je zřejmé, že má-li cyklus skončit, musí příkaz v těle cyklu zajistit, aby podmínka přestala platit. Pokud je třeba v těle cyklu vykonat více příkazů, vytvoříme z nich složený příkaz. (begin…end) Komponenta SpinEdit Protože budeme často pracovat s celými čísly, můžeme pro jejich vstup používat komponentu SpinEdit, kterou najdeme na paletě komponent Samples.Z jejích vlastností použijeme Value, což je celočíselná hodnota na vstupu. MinValue a MaxValue omezuje rozsah vstupu, Increment je přírůstek, o který se mění Value, pokud používáme šipky vlevo. Příklad 1. Zobrazte pětkrát za sebou zprávu, pokaždé u ní bude její pořadové číslo. Rozbor: Použijeme proměnnou jako počítadlo, jejíž hodnota se při každém průchodu cyklem zvýší o jedničku. Dalším příkazem v těle cyklu bude zobrazení příslušné zprávy. var i:integer; begin i:=1; while i<=5 do begin showmessage('baf '+inttostr(i)); inc(i); end; end; Příklad 2. Vypište všechny dělitele daného čísla. 1. verze Budeme postupně testovat všechny adepty od 1 do daného čísla, pokud adept číslo děli, převedeme ho na řetězec a přidáme do výstupního řetězce, který nakonec vypíšeme. var adept,cislo:integer;vystup:string; begin cislo:=spinedit1.value;

PDF created with pdfFactory trial version www.pdffactory.com

Page 22: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

vystup:='Delitele: '; adept:=1;{1. adept je 1} while adept<=cislo do {dokud neprobereme vsechny adepty} begin if cislo mod adept =0 {kdyz je cislo delitelne adeptem} then vystup:=vystup+' '+ inttostr(adept); {pridame ho do vystupniho retezce} adept:=adept+1; {prejdeme na dalsiho adepta} end; showmessage(vystup); end; Vylepšení: Dělitele můžeme hledat pouze do poloviny čísla (a číslo samo později doplnit), případně pouze do odmocniny (Z matematiky víme, že každé složené číslo má alespoň jednoho dělitele menšího nebo rovného odmocnině z čísla) a dělitele většího než odmocnina průběžně dopočítávat. V původním příkladu jsme pro číslo x testovali také x adeptů. V druhém případě jich testujte pouze sqrt(x). Příklad 2. Celočíselné dělení: Vypočítejte podíl a zbytek při celočíselném dělení pouze pomocí odčítání, aniž byste použili operátorů div a mod. 32 : 9: 32-9=23-9=14-9=5 Devítku jsme odečítali třikrát – a to je podíl, zbytek je 5 – číslo menší než dělitel. Budeme tedy postupně odečítat dělitele, dokud nebude menší než to co zbyde {eventuelně roven, pokud by byl zbytek nula) a průběžně počítat, kolikrát jsme odečítali. Jako počítadlo (podíl) použijeme opět proměnnou, jejíž hodnota se při každém odečtení (průchod cyklem) zvětší o jedničku. var zbytek, delitel,delenec, podíl:integer; … zbytek:=delenec; podíl:=0; While zbytek>=delitel do begin zbytek:=zbytek-delitel; podil:=podil+1; end;

Cvičení: 1. Proveďte vylepšení příkladu s výpisem dělitelů. 2. Naprogramujte výpočet největšího společného dělitele dvou čísle podle definice – jako největší číslo, které obě dělí. 3. Naprogramujte podobně největší společný násobek dvou čísel. (nejmenší číslo, kterým jsou obě dělitelná)

Řešení: 1. var adept,cislo,odmocnina:integer;vystup:string; begin cislo:=spinedit1.value; vystup:='Delitele: 1 '; adept:=2; odmocnina:=trunc(sqrt(cislo)); while adept<=odmocnina do begin if cislo mod adept =0 then vystup:=vystup+' '+ inttostr(adept)+' '+inttostr(cislo div adept)+' ';

PDF created with pdfFactory trial version www.pdffactory.com

Page 23: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

adept:=adept+1; end; vystup:=vystup+' '+inttostr(cislo); showmessage(vystup); end; 1. lépe procedure TForm1.Button2Click(Sender: TObject); var adept,cislo,odmocnina:integer;vystup:string; begin cislo:=spinedit1.value; vystup:='Delitele: 1 '; adept:=2; odmocnina:=trunc(sqrt(cislo)); while adept<=odmocnina do begin if cislo mod adept =0 then if (cislo div adept)<>adept then vystup:=vystup+' '+ inttostr(adept)+' '+inttostr(cislo div adept)+' ' else vystup:=vystup+' '+ inttostr(adept)+' '; adept:=adept+1; end; vystup:=vystup+' '+inttostr(cislo); showmessage(vystup); end; 2. var a,b,nsd:integer; begin a:=spinedit1.value; b:=spinedit2.value; if a>b then nsd:=b else nsd:=a;{adept je nejprve mensi z obou cisel, pokud obe nedeli, budeme ho postupne zmensovat} while (a mod nsd <>0) or (b mod nsd <>0) do nsd:=nsd-1; showmessage(inttostr(nsd)); end; 3. procedure TForm1.Button1Click(Sender: TObject); var a,b,nsn:integer; begin a:=spinedit1.value; b:=spinedit2.value; if a>=b then nsn:=a else nsn:=b; while (nsn mod a <>0) or (nsn mod b <>0) do nsn:=nsn+1;; showmessage(inttostr(nsn)); end;

8. Cykly – příkaz repeat V příkazu while se podmínka setrvání v cyklu testovala na začátku, většina programovacích jazyků a Delphi rovněž, poskytují programátorovi další typ příkazu – kde se nejprve provede příkaz a poté se testuje podmínka. Má tvar: Repeat příkaz nebo řada příkazů Until podmínka.;

PDF created with pdfFactory trial version www.pdffactory.com

Page 24: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Nejprve se provedou příkazy v těle cyklu, pak se otestuje podmínka. Je-li splněna, cyklus se ukončí, jinak se pokračuje prováděním příkazů. Všimněte si, že na rozdíl od while podmínka určuje ukončení cyklu. Klíčová slova Repeat, Until mají také význam příkazových závorek, takže pokud v těle cyklu chceme provést více příkazů, není třeba z nich vytvořit příkaz složený vkládáním mezi begin a end. Příklad 1. Vypočítejte součet čísel 1+2+3+….n, vstupem je n – přirozené číslo. (Příklad je uveden z cvičných důvodů, z matematiky víme, že součet této posloupnosti jde vyjádřit vzorečkem n/2*(1+n) ). Rozbor: Potřebujeme do nějaké proměnné postupně přidávat čísla 1,2,…až n nebo v opačném pořadí n, n-1..až . Při každém průchodu cyklem tedy přidáme do celkového součtu číslo – nejprve n, pak n-1… Postup budeme opakovat, dokud přidávané číslo není rovno 0. var n,suma:integer; begin n:=StrToInt(edit1.text); suma:=0; repeat suma:=suma+n; n:=n-1; until n=0; showmessage(inttostr(suma)); end; Příklad 2. Vypočítejte ciferný součet vstupujícího celého čísla. Rozbor: Protože dopředu nevíme, kolikaciferné je číslo, musíme začít odzadu. Postupně vždy zjistíme poslední cifru (operace mod 10) a číslo o ni zkrátíme. (operace div 10), až z původního čísla zbyde nula. var n,cs:integer; begin n:=StrToInt(edit1.text); cs:=0; repeat cs:=cs + n mod 10; n:=n div 10; until n=0; showmessage(inttostr(cs)); end;

Trasování je v podstatě provádění programu po jednotlivých příkazech, přičemž sledujeme, jak se mění hodnoty proměnných. Využíváme ho zvlášť při hledání logických chyb – když program sice pracuje, ale nedává výsledky, jaké bychom očekávali. Dá se provádět „ručně“ – tak, že si připravíme tabulku potřebných proměnných a zapisujeme si do ní hodnoty. Pro předchozí příklad, vstup: n=1234 by mohla vypadat takhle: průchod cyklem n cs 0 1234 0 1 123 4 2 12 7 3 1 9 4 0 10 Pohodlnější ovšem je, nechat většinu práce na počítači. Protože klasické okenní programy obvykle čekají ve smyčce na nějakou akci uživatele, je třeba si nejdřív nastavit body přerušení – tj. kam se dojde, než trasování začne. Provedeme to například kliknutím do sloupce vlevo vedle kódu programu, objeví se tam červený puntík a řádek se červeně vysvítí. Další kliknutí breakpoint odebere. Sledované hodnoty si připravíme do kukátka – okno Watch: Run/Add Watch (Ctrl F5) Zapisujeme každou zvlášť do políčka Expression.

PDF created with pdfFactory trial version www.pdffactory.com

Page 25: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Program pak spustíme a po zadání příslušné hodnoty trasujeme buď Run/Trace Into nebo stačí opakovaně mačkat klávesu F7 a ve Watch listu sledovat. jak se mění peoměnné.

Porovnání cyklů while a repeat Připomínáme, že oba cykly se liší jednak tím, že u repeatu se příkaz v těle cyklu provede vždycky, jednak tím, že zatímco podmínka u while je podmínkou setrvání v cyklu, u repeat se jedná o podmínku opuštění cyklu. Vyjádření while pomocí repeat: While Podmínka do Příkaz: If Podmínka Then Repeat Příkaz Until not Podmínka; Vyjádření repeat pomocí while: Repeat Příkaz Until Podmínka Begin Příkaz; While not Podmínka do Příkazů End; Not je operátor negace, patří k operátorům logickým a má nejvyšší prioritu. Pozor! Uvědomte si, že negujete-li složenou podmínku, platí: Not (A and B) = Not A or Not B Not (A or B) = Not A and Not B

Generátor náhodných čísel nám poskytuje pseudonáhodná čísla, vypočítaná podle určitého algoritmu. Random – je funkce, jejíž funkční hodnotou je desetinné náhodné číslo z intervalu <0, 1), vhodným násobenám získáme čísla větší. Random(p) kde p je přirozené číslo poskytuje náhodné přirozené číslo z množiny {0,1,…p-1}, chce-me-li tedy generovat náhodná přirozená čísly v rozmezí {a..b}, použijeme Random(b-a+1)+a. Aby vznikající řada čísel nebyla při každém spuštění programu stejná, je třeba inicializovat generátor procedurou randomize. Příklad 3.: Vygenerujte 5 náhodných čísel mezi 0 do 10, zobrazte je a vypočítejte jejich součet. V cyklu budeme vždy generovat nové číslo, přidáme ho jednak do výstupního řetězce, jednak do proměnné součet a navíc vždy zvýčíme hodnotu proměnné počet o jedničku, abychom věděli, kdy máme skončit.

kukátko

bod přerušení

co se bude provádět dalším F7

PDF created with pdfFactory trial version www.pdffactory.com

Page 26: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

var pocet, soucet, cislo:integer;vystup:string; begin pocet:=0; soucet:=0; randomize; vystup:=''; repeat cislo:=random(11); soucet:=soucet+cislo; vystup:=vystup+inttostr(cislo)+' '; pocet:=pocet+1; until pocet=5; showmessage(vystup+#13+'soucet:'+ Inttostr(soucet)); end; Mazání události komponenty Vymažeme kód mezi begin a end a při dalším spuštění programu systém proceduru odstraní. (Pokud byste ji vymazali celou, zůstane uvedena v deklaraci formuláře a může způsobit problémy)

Cvičení 1. Vypočítejte faktoriál vstupujícího čísla n! = 1*2*3….*n (Pozor, hodnoty rostou velice rychle, takže může dojít k přetečení a pro větší vstup dostanete podivné výsledky. Vyzkoušejte.) 2. Vytvořte k danému vstupujícímu číslo číslo, které má tytéž cifry, ale v opačném pořadí. 3. Vygenerujte 10 náhodných čísel a zjistěte, kolik z nich je sudých. 4. Vyzkoušejte si pomocí generátoru náhodných čísel házení kostkou. V kolikátém hodu padne poprvé šestka? (Čísla pro kontrolu zobrazte )

Řešení: 1. var n,i,f:integer; begin n:=StrToInt(edit1.text); f:=1; i:=1; repeat f:=f*i;; i:=i+1; until n<i; showmessage(inttostr(f)); end; 2. var n,obr:integer;s:string; begin n:=StrToInt(edit1.text); s:='';{pomocny retezec, do kterho si budeme odpredu ukladat cifry usekavane z puvodniho cisla odzadu} repeat s:=s+IntTostr(n mod 10); n:=n div 10; until n=0; obr:=strtoint(s); showmessage(s); end; 3. var pocet, pocsud, cislo:integer;vystup:string; begin pocet:=0; pocsud:=0; randomize; vystup:=''; repeat cislo:=random(11);

PDF created with pdfFactory trial version www.pdffactory.com

Page 27: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

if cislo mod 2=0 then pocsud:=pocsud+1; vystup:=vystup+inttostr(cislo)+' '; pocet:=pocet+1; until pocet=5; showmessage(vystup+#13+'pocet sudych:'+ Inttostr(pocsud)); end; 4. var pocet, cislo:integer;vystup:string; begin pocet:=0; randomize; vystup:=''; repeat cislo:=random(6)+1; vystup:=vystup+inttostr(cislo)+' '; pocet:=pocet+1; until cislo=6; showmessage(vystup+#13+'pocet hodu:'+ Inttostr(pocet)); end;

9. Skalární (jednoduché) typy dat Typy dat v Object Pascalu se dají dělit podle různých hledisek – na jednoduché a strukturované, standardní a definované programátorem, ordinální a jiné. Postupně se se všemi seznámíme. Datový typ určuje: • Jméno – identifikátor (Integer) • Množina přípustných hodnot • Množina přípustných operací

Ordinální typy: množina hodnot je uspořádaná (od nejmenšího k největšímu), každému prvku lze přiřadit jeho pořadové (ordinální) číslo. (Pojem pochází z matematiky, kde ordinální čísla jsou například čísla přirozená, celá nebo racionální. Při implementaci na počítači zřejmě nemůže být množina přípustných hodnot nekonečná.) Jsou pro ně definovány funkce: • předchůdce – pred(x), • následník – succ(x), • pořadové číslo – ord(x) • největší prvek – high(x) • nejmenší prvek – low(x) a procedury: • Inc(x): x:=succ(x) • Dec(x): x:=pred(x)

Standardní typy: Standardní zde znamená, že je naleznete v každé implementaci Pascalu od Turbo Pascalu po Delphi. Boolean Množina hodnot={False, True} Množina logických hodnot je uspořádaná – False<True, ord(False)=0, succ(False)=True. Operace: and, or, not, xor (výlučné nebo), <= (implikace), = (ekvivalence), <> (not je oprátor negace) Proměnná typu Boolean zabírá v paměti 1 B. Integer velikost záleží na procesoru – standardní Pascal v každém případě 2B, takže se dá pracovat s čísly od -32768..32767, Delphi 32bitové – 4B, odpovídá typu longint ve standardním Pascalu. Obecně: -Maxint-1,….Maxint

PDF created with pdfFactory trial version www.pdffactory.com

Page 28: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Maxint je standardní identifikátor typu Integer, to, že záporných čísel je o jednu víc vyplývá z jejich implementace ve dvojkovém doplňkovém kódu. (Ještě bude) Prakticky se užívají podtypy – Word, Byte, Longint, Shortint aj. (Více – viz. Nápověda Delphi) Množina hodnot – podmnožina celých čísel Operace: +, -, *, div, mod, abs(x), sqr(x), trunc(x) Výhodou tohoto typu je přesná aritmetika, nevýhodou možnost přetečení, pokud se výsledek nevejde do paměti. Char Množina hodnot: množina znaků ASCII kódu, zobrazení do 1 B (255 znaků) Operace: <, =, <=, >=, <> Ord(x), inverzní funkce chr(ord(x))=x pred(x) = chr(ord(x)-1) ord(‘A’) = 65 ord(‘B’) = 66 3=ord(‘3’) - ord(‘0’) UpCase(‘a’) =’A’ – převede malé písmeno na velké, jinak nedělá nic. (Hodnota vstupního znaku se nemění) Real – je standardní, není ordinální Množina hodnot – podmnožina racionálních čísel –2.9 e-39..1.7e-38 podtypy (single, double, extended, comp) – kromě rozsahu se liší také počtem platných číslic – real 11-12, extended 19-20 Kromě nuly existuje strojová nula (0, minreal), pokud je výslodek výpočtu menží než minreal, počítač ho považuje za nulu. Reálná čísla se zobrazují s omezenou přesností, (vyplývá to jednak z jejich dvojkové reprezentace v počítači, jednak ze skutečnosti, že případný nekonečný počet desetinných míst je nutno někde ukončit) pozor na možné zacyklení. Operace abs(x), sqr(x), sqrt(x), sin(x), cos(x), arctan(x), ln(x). exp(x), trunc(x), round(x), int(x) Frac(x) – desetinná část argumentu Konstanta Pi

Komponenta Listbox se používá pro výstup většího množství textu. Budeme zatím využívat především její metodu Listbox1.items.add(‘retezec’), která vloží do boxu řetězec, vždy na zvláštní řádek. Podobně jako editační políčko má listbox metodu clear, která ho vyprázdní. (Listbox1.clear). Funkce Sizeof(x) vrací velikost objektu x v bytech, takže nám pomůže zjistit, kolik paměti dané x zabírá. Například pro x typu Boolean, je SizeOf(x)=1. Příklad: Vygenerujte 20 náhodných čísel od 0 do 100, zobrazte je do Listboxu a vytiskněte největší a nejměnší z nich. Rozobor: Jak budeme číslo generovat, převedeme je vždy na řetězec a zobrazíme, přitom každé číslo porovnáme s maximem, pokud je větší, uložíme do maxima, pokud je menší, provnáme ho ještě s minimem. Efektivnější, ale pracnější způsob by spočíval ve zpracování čísel po dvojicích (viz maximum ze čtyř) var x,i,min,max:integer; begin i:=0; randomize; max:=low(integer); min:=high(integer); {inicializujeme hodnoty tak, aby v nich nemohla zustat nejaka puvodni hodnota} repeat Inc(i); x:=random(100); Listbox1.Items.Add(IntToStr(x)); if x<min then min:=x else if x>max then max:=x;

PDF created with pdfFactory trial version www.pdffactory.com

Page 29: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

until i=10; listbox1.items.add('************'); listbox1.items.add('max='+inttostr(max)); listbox1.items.add('min='+inttostr(min)); end; .

Cvičení 1.Umístěte na formulář editační políčko a komponentu Listbox. Po stisknutí klávesy Enter v editačním políčku, se text přesune do Listboxu, editační políčko se vyprázdní a připraví k dalšímu psaní.. 2. Umístěte na formulář tlačítko pojmenovaná Integer , na jeho stisknutí se zobrazí největší a nejmenší hodnota daného typu a velikost typu v bytech. 3. Umístěte na formulář komponentu Label popsanou velkým číslem -10. Když na komponentu klepneme změní se caption na následníka původního captionu. (Pokračuje pořád dál…) 4. Vygenerujte a do listboxu zobrazte řadu jednociferných čísel, poslední generované číslo bude 9. Vypočítejte aritmetický průměr těchto čísel. 5. Vygenerujte a do listboxu zobrazte řadu 10 dvojciferných čísel. Vytiskněte o kolik je víc čísel sudých než lichých.

Řešení 1. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if key=#13 then begin Listbox1.Items.Add(edit1.text); Edit1.clear; Edit1.setFocus; end; end; 2. procedure TForm1.Button4Click(Sender: TObject); begin showmessage(inttostr(low(integer))); showmessage(inttostr(sizeof(integer))); showmessage(inttostr(high(integer))); end; 3. procedure TForm1.Label1Click(Sender: TObject); var s:string; x:integer; begin x:=StrToint(label1.caption); inc(x); label1.caption:=inttostr(x); end; 4. procedure TForm1.Button6Click(Sender: TObject); var x,p:integer;s:real; begin randomize; listbox1.clear; s:=0; p:=0; repeat x:=random(10); inc(p); s:=s+x; Listbox1.Items.Add(IntTostr(x)); edit1.clear;

PDF created with pdfFactory trial version www.pdffactory.com

Page 30: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

edit1.setfocus; until x=9; showmessage(floattostr(s/p)); end; 5. procedure TForm1.Button7Click(Sender: TObject); var x,i,sud,lich:integer; begin sud:=0;lich:=0; listbox1.clear;i:=0; repeat Inc(i); x:=random(100); Listbox1.Items.Add(IntToStr(x)); if odd(x) then inc(lich) else inc(sud) until i=10; if lich>sud then showmessage('lichych je vic o'+ inttostr(lich-sud)) else if lich=sud then showmessage('je jich stejne') else showmessage('sudych je vic o'+ inttostr(sud-lich)) end;

10. Cyklus FOR Tento ty cyklu používáme výhradně tehdy, víme-li dopředu, kolikrát se bude opakovat. Příklad: chceme-li do výstupního řetězce umístit 100 vykřičníků: Var s:string;i:integer; Begin s:=’’; For i:=1 to 100 do s:=s+’!’ End; Obecně: For p:=a to b do Příkaz; Funguje následujícím způsobem: If a<=b then Begin P:=a; Příkaz; While p<=b do Begin inc(p); Příkaz; End; End; a – dolní mez cyklu b – horní mez p – řídící proměnná Proměnné a, b a p by v průběhu cyklu neměly být měněny, dál je z předchozího popisu zřejmé, že mohou být pouze ordinálního typu. I když existují příkazy break a continue, které umožňují ukončit cyklus dřív, dáváme v tom případě přednost cyklu while nebo repeat. Pokud chceme krokovat shora dolů, (a>=b) můžeme použít variantu For cyklu: For a downto b do Příkaz;

Priorita operací: v Object Pascalu vychází z matematiky, pokud si nejsme jisti, používáme závorky. 1. Použití funkce a operátoru not

PDF created with pdfFactory trial version www.pdffactory.com

Page 31: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

2. * / div mod and (multiplikativní operátory) 3. + - or xor (aditivní operátory) 4. < > =… relační operátory Formátování reálných čísel v Delphi Prohlédněme si nápovědu na funkci FloattostrF (F1 na slově) function FloatToStrF(Value: Extended; Format: TFloatFormat; Precision, Digits: Integer): string; Tato funkce tedy převádí reálné číslo na řetězec, ale volbou parametrů můžeme ovlivnit jeho tvar. Příklad: Listbox1.Items.Add(floattostrf(pi,FfFixed,6,2)); vloží do Listboxu 3,14. (Digits udává počet míst za desetinnou čárkou) Příklady: Příklad 1. ASCII kód: var i:integer; ch:char; begin listbox1.clear; for i:=1 to 255 do listbox1.items.add(inttostr(i)+'...'+chr(i)); end; Příklad 2. Tabelace funkce y=2x-1 od 0 do 1 s krokem 0.1 Protože cyklus for v Pascalu na rozdíl od některých jiných jazyků neumožňuje zvyšovat hodnotu řídící proměnné o reálnou konstantu, použijeme pouze skutečnosti, že budeme tisknout 11 řádků tabulky. V každém kroku přitom zvýšíme hodnotu x o 0.1, vypočítáme y a obě hodnoty vytiskneme. procedure TForm1.Button3Click(Sender: TObject); var i:integer;x,y:real; begin listbox1.clear; listbox1.items.add('x 2*x-1'); x:=0; for i:=1 to 11 do begin y:=2*x-1; listbox1.items.add(floattostrf(x,fffixed,2,2)+' ' + floattostrf(y,fffixed,2,2)); x:=x+0.1; end; end; Příklad 3. Vygenerujte do Listboxu řadu náhodných čísel (počet určuje konstanta) a vytiskněte největší z nich. (Počet čísel zadejte konstantou) Do proměnné max nejprve umístíme nejmenší záporné celé číslo, potom v těle cyklu vždy generujeme a zobrazujeme číslo a je-li větší, ukládáme ho do proměnné max. const n=10; var i,max,x:integer; begin randomize; max:=-maxint-1; for i:=1 to n do begin x:=random(10); listbox1.items.add(inttostr(x)); if x>max then max:=x; end; showmessage(inttostr(max)); end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 32: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Cvičení: 1. Vypočítejte pro vstupující číslo n jeho faktoriál: n! = 1.2.3…n s využitím For cyklu 2. Tabelace funkce y = 2x-1 pomocí cyklu Repeat. (Meze zadá uživatel, krok může být opět 0.1) 3. Maximum a počet maxim (Vstup z generátoru) Řešení: 1. var n,i,fakt:integer; begin n:=spinedit1.value; fakt:=1; for i:=1 to n do fakt:=fakt*i; showmessage(IntTostr(fakt)); end; 2. var a,b,x,y:real; begin a:=StrTofloat(edit1.text); b:=strtofloat(edit2.text); x:=a-0.1; repeat x:=x+0.1 ; y:=2*x-1; listbox1.items.add(floattostrf(x,fffixed,2,2)+' ' + floattostrf(y,fffixed,2,2)); until x>=b; end; 3. var i,max,x,p:integer; begin randomize; p:=0; max:=-maxint-1; for i:=1 to n do begin x:=random(10); listbox1.items.add(inttostr(x)); if x>max then begin max:=x; p:=1; end else if x=max then inc(p); end; showmessage(inttostr(max)+' '+inttostr(p)); end;

11. Typ interval a větvení case

Intervalový typ Tento datový typ specifikuje neprázdnou souvislou podmnožinu hodnot nějakého ordinálního typu. Dolní a horní mez je dána konstantami typu. Příklady: Type Malint=0..9; Cifry=’0’..’9’; Var x:Malint; y:Cifry; X pak může nabývat hodnot celých čísel od 0 do 9, y znaků od ‘0’ do ‘9’. Intervalový typ omezuje pouze množinu přípustných hodnot, pro objekt typu interval můžeme používat všechny operace a funkce jako pro jeho hostitelský typ. (V tomto případě Integer a Char)

PDF created with pdfFactory trial version www.pdffactory.com

Page 33: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Poznámka: Delphi kontrolují dodržování hodnot, pokud je program přeložen s direktivou $R+ – zapnuta kontrola rozsahu hodnot (range checking), jinak má použití tohoto typu význam spíš pro čitelnost a srozumitelnost programu.

Větvení case Je další variantou podmíněného příkazu, používá se tam, kde potřebujeme víc vnořených příkazů IF. Může mít tvar: Case Výraz of Hodnota1: Příkaz1; Hodnota2: Příkaz2; ……. HodnotaN: PříkazN; End; Nebo: Case Výraz of Hodnota1: Příkaz1; Hodnota2: Příkaz2; ……. HodnotaN: PříkazN; Else JinýPříkaz; End; Výraz musí být ordinálního typu, pokud nabývá hodnoty H1, provede se příkaz Příkaz1 atd. Else použijeme, pokud chceme, aby se JinýPříkaz provedl, když výraz nenabývá žádné z hodnot H1 až Hn. Kromě jednotlivé hodnoty v příkazu Case můžeme použít interval nebo několik hodnot, oddělených čárkami.

Přepínací tlačítko (Radiobutton) Najdeme na paletě komponent Standard, důležitá je jeho vlastnost checked, typu boolean, která udává, zda je tlačítko zaškrtnuto. If Radiobutton1.checked then… Pokud na tlačítko klepneme myší, změní se hodnota checked a generuje se událost OnClick. Pokud chceme totéž provozovat bez zásahu uživatele, stačí do kódu programu napsat: Radiobutton1.checked:=not Radiobutton1.checked Tato tlačítka se většinou sdružují do skupin, z nichž může být vybráno pouze jedno. Potom můžeme s výhodou použít komponentu Radiogroup, rovněž z palety komponent Standard. Seznam tlačítek je uložen ve vlastnosti Items a můžeme ho vytvářet a upravovat pomocí String List Editoru., který se spustí, když klepneme na tlačítko s třemi tečkami vedle položky Items. Skupina umožňuje výběr jediného tlačítka, jehož číslo (počítáno od nuly) je ve hodnotou vlastnosti ItemIndex. Chceme-li např. vybrat tlačítko za vybraným: Radiogroup1.ItemIndex:= Radiogroup1.ItemIndex+1 Větvení programu podle zaškrtnutého políčka: case radiogroup1.itemindex of 0: p1; 1: p2; … n: pn; end; Není-li vybráno žádné tlačítko, jei ItemIndex = -1.

PDF created with pdfFactory trial version www.pdffactory.com

Page 34: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Zaškrtávací políčko (Checkbox) Zde je povolen výběr více políček, pro indikaci výběru můžeme opět použít vlastnost checked, navíc lze využít vlastnosti state, která má tři stavy: cbChecked (vybrané), cbUnChceked (nevybrané) cbGrayed (podšeděné), pokud je vlastnost Alowgrayed nastavena na true. Dají se sdružovat pomocí komponenty GroupBox. (dále)

Příklady: 1. Napište program pro výpočet jízdného. Vstupovat bude délka cesty v celých km, cenü za km definuje následující tabulka: Vzdálenost Cena za km 0..19 15 20..30 12 31..50 10 více než 50 8 var zakm,km,cena:integer; begin km:=spinedit3.value; case km of 0..19: zakm:=15; 20..30: zakm:=12; 31..50: zakm:=10; else zakm:=8; end; cena:=km*zakm; showmessage(inttostr(cena)); end; Zadání pásem vzdáleností můžeme řešit pomocí komponenty radiogroup, kde si uživatel pásmo vybere. var cena:integer;celkem,km:real; begin case radiogroup1.itemindex of 0:cena:=15; 1:cena:=20; 2:cena:=10; 3:cena:=8; end; km:=StrToFloat(edit1.text); celkem:=cena*km; showmessage(floattostr(celkem)); end; 2. Vstupem jsou dvě celá čísla, výstupem je správa, zda je jedno z nich dělitelné druhým. Dělenec zadejte pomocí spineditu, možné dělitele radiogroupem. (2,3,4,5,6,…) Pokud tvoří dělitelé souvislou řadu přirozených čísel, můžeme s výhodou použít vlastnosti ItemIndex. var x,y:integer; begin x:=spinedit2.value; y:=radiogroup2.itemindex+2; if x mod y = 0 then showmessage('dělí') else showmessage('nedělí') end; 3. Uživatel si může zaškrtnutím políčka vybrat některá čísla z nabídky, po stisknutí tlačítka se zobrazí jejich součet. var sum:integer; begin sum:=0; if checkbox1. checked then sum:=sum+strtoint(checkbox1.caption); if checkbox2. checked then sum:=sum+strtoint(checkbox2.caption);

PDF created with pdfFactory trial version www.pdffactory.com

Page 35: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

….. Toto (nepěkné) řešení jde elegantně zjednodušit, pokud použijeme pole komponent a přetypování proměnných – dále.

Cvičení 1. Vstupem je měsíc, výstupem počet dnů v něm. (Pro vstup použijte komponentu Radiogroup). 2. Vstupem jsou body za test (Intervaly hodnocení si vymyslete), výstupem známka 3. Modelujte pomocí generátoru náhodných čísel vrh kostou, počet hodů zadá uživatel. Vytiskněte jednak výsledky jednotlivých vrhů, jednak kolikrát co padlo. Řešení: 1. var pocet,rok:integer; begin case radiogroup1.itemindex of 0,2,4,6,7,9,11:pocet:=31; 1: begin rok:=spinedit1.value;

if rok mod 4=0 then pocet:=29 else pocet:=28 end; else pocet:=30; end; showmessage(inttostr(pocet)); end; Poznámka: Ve skutečnosti jsou přetsupná celá staletí pouze, když jsou dělitelná 400. 2. Jednodušší varianta jízdného 3. var i,hod,p1,p2,p3,p4,p5,p6:integer; begin randomize; p1:=0;p2:=0;p3:=0;p4:=0; p5:=0;p6:=0; for i:=1 to 20 do begin hod:=random(6)+1; listbox1.items.add(inttostr(hod)); case hod of 1:inc(p1); 2:inc(p2); 3:inc(p3); 4:inc(p4); 5:inc(p5); 6:inc(p6); end; end; showmessage('1: '+inttostr(p1)+#13+ '2: '+inttostr(p2)+#13+ '3: '+inttostr(p3)+#13+ '4: '+inttostr(p4)+#13+ '5: '+inttostr(p5)+#13+ '6: '+inttostr(p6)); end;

12. Správnost a efektivnost algoritmu Úplná správnost: Algoritmus skončí a řeší daný problém. Parciální správnost: Pokud algoritmus skončí, řeší daný problém.

PDF created with pdfFactory trial version www.pdffactory.com

Page 36: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Dokázat obecně správnost algoritmu je záležitost více matematická a teoreticky obtížná. Proto obvykle algoritmus testujeme – tedy realizujeme pro nějaké vstupní hodnoty. Cílem testování je spíš nalézt chyby, pokud nemůžeme takto otestovat celou množinu možných vstupních hodnot, nejedná se o důkaz správnosti.

Časová a paměťová složitost, optimalizace Ze dvou algoritmů řešících stejnou úlohu je časově efektivnější ten, jehož realizace vyžaduje méně porovnatelných kroků. (Měl by trvat kratší dobu) Paměťově efektivnější algoritmus ptřebuje méně místa. (např. proměnných) Přesněji chápeme časovou a paměťovu složitost algoritmu jako funkci, která velikosti problému (např. počet vstupujících prvků) přiřazuje počet operací vykonaných při výpočtu. Rozlišujeme časovou složitost v nejhorším (případně nejlepším) případě a v průměrném případě (hůře se určuje). Pokud není předem udána velikost vstupních dat, uvažujeme n hodně velké. (např. lineární složitost 10n > kvadratická n*n do 10) Pro malá data jde totiž prakticky použít i horší algoritmus. Pro ona velká data pak hovoříme o asymptotické časové složitosti. Například používáme zápis O (n2), pokud je počet operací 2n2 + 3n +100. V případě polynomu tedy určuje tuto složitost člen s nejvyšší mocninou n. V praxi užívané algoritmy mají většinou složitost O(n2), O(n), O(logn),…(kvadratický, lineární, logaritmický…) Polynomiální – složitost jde omezit polynomem. Exponenciální – s vyšší složitostí, často O(2n), pokud je n>50, jsouž prakticky nepoužitelné. Optimalizace – úprava algoritmu na efektivnější tvar. Několik optimalizačních pravidel: • Neprovádět v cyklu opakovaně to, co jde provést před ním (Vyjímání před cyklus) • Optimalizace těla cyklu • Spojování cyklů, je-li to možné • Využívání předchozích výsledků • Metoda Rozděl a panuj (dále) • Využívání zvláštností aritmetiky počítačů (díky binární reprezentaci dat v počítači jsou operace dělení,

násobení dvěma a test na sudost rychlejší než běžné aritmetické opeace) • Rychlé vyhodnocování logických výrazů • Speciální vlastnosti problému (Euklidův algoritmus) Pozor na zachování čitelnosti a srozumitelnosti programu při optimalizaci.

Příklady: 1. Naprogramujte výpočet největšího společného dělitele dvou čísel podle definice (největší číslo, které obě

dělí) a podle Euklidova algoritmu. Porovnejte efektivnost obu metod. Zdůvodněte správnost Euklidova algoritmu.

Euklidův algoritmus pro výpočet největšího společného dělitele dvou čísel vychází ze skutečnosti, že nsd dvou čísle je také nsd libovolného z nich a jejich rozdílu. Tedy: Nsd(a,b)=nsad(a-b,b) když a>b; Nsd(a,b)=nsd(b-a,a) kdy a<b; Nsd(a,b)=a=b, když a=b. Konkrétně: Nsd(32,24)=nsd(24,8)=nsd(16,8)=nsd(8,8)=8. Myšlenka důkazu správnosti Euklida: d/x and d/y => d/x-y, takže nsd(x,y)=nsd(x,y-x). Nsd vstupující dvojice je nsd dvojice vystupující. Protože se čísla, se kterými pracujeme stále zmenšují, algoritmus po konečném koku skončí – pokud jsou čísla nesoudělná, zastaví se o jedničku. Varianty řešení: 1.1. While x<>y do If x>y then y:=y-x Else x:=x-y; Nsd:=x; Tato varianta je nejjednodušší, ale pokud by jedno z čísel bylo podstatně větší než druhé, (což může nastat i během výpočtu) testujeme zbytečně obě podmínky, i když se pořád pohybujeme v jedné větvi. Vylepšení: 2.2. While x<>y do

PDF created with pdfFactory trial version www.pdffactory.com

Page 37: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Begin while x>y do x:=x-y; While y>x do y:=y-x; End; Nsd:=x; Třetí uvedená varianta vychází z toho, že opakované odčítání vlastně vede k získání zbytku po celočíselném dělení: Repeat x:=x mod y; {x:=x-y, dokud x>=y} Vymen(x,y); {y:=y-x…} Until y=0; Nsd:=x; 2. Prvočíslo Napište program, který zjistí, zda vstupující číslo je prvočíslo nebo číslo složené. 0. varianta: Hledáme dělitele mezi všemi čísly menšími než dané. 1. varianta: Hledáme dělitele mezi čísly menšími nebo rovnými polovině daného. 2. varianta: Testujeme možné dělitele do odmocniny z čísla. 3. varinata: Protože liché číslo nemá sudé dělitele, zjistíme nejprve zda jde o sudé číslo (poku to není dvojka, jedná se o číslo složené), pak zkoumáme možné liché dělitele lichého čísla do odmocniny. 2. var adept, odm, cislo:integer; begin odm:=trunc(sqrt(cislo)); adept:=2; while (adept<=odm) and (cislo mod adept<>0) do inc(adept); if adept>odm then showmessage(‘prvocislo’) else showmessage(‘cislo slozene’); end; 3. var adept, odm, cislo:integer; begin cislo:=spinedit1.value; if odd(cislo) then begin odm:=trunc(sqrt(cislo)); adept:=3; while (adept<=odm) and (cislo mod adept<>0) do inc(adept,2); if adept>odm then showmessage('prvocislo') else showmessage('cislo slozene'); end else if cislo=2 then showmessage('prvocislo') else showmessage('cislo slozene'); end;

Cvičení: 1. Vypočítejte největší společný násobek dvou čísel. 2. Naprogramujte generátor náhodných řetězců z písmen velké anglické abecedy. (A..Z). Délu řetězce zadá uživatel. 3. Maximum a druhé maximum Řešení: 1. (nsn(a,b)=a*b div nsd(a,b) 2. var delka,pocet,y:integer;s,vystup:string; x:char; begin delka:=spinedit1.value; s:='';

PDF created with pdfFactory trial version www.pdffactory.com

Page 38: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

for pocet:=1 to delka do begin y:=random(26); x:=chr(ord('A')+y); s:=x+s; end; showmessage(s); end; 3. var x,i,max,max2:Integer; begin randomize; max:=-maxint; max2:=max; for i:=1 to 20 do begin x:=random(20); listbox1.items.add(Inttostr(x)); if x>max then begin max2:=max; max:=x; end else if (x>max2) and (x<>max) then max2:=x; end; showmessage(inttostr(max)+' '+inttostr(max2));

13. Vnořené cykly Často potřebujeme použít cyklus v cyklu, použití těchto konstrukcí si ukážeme na příkladech. 1. Vypište do listboxu trojúhelník z hvězdiček. (V prvním řádku bude jedna, ve druhém dvě, ..v desátem deset) Tiskneme-li i-tý řádek, je na něm i hvězdiček, Použijeme tedy dva cykly – vnější pro tisk i-tého řádku a vnitřní, kdy vytvoříme řetězec obsahující i hvězdiček a vytiskneme ho. (Problém jde ovšem vyřešit pomocí jediného cyklu, což je efektivnější, viz cvičení.) var s:string;i,j:integer; begin listbox1.clear; for i:=1 to 20 do begin s:=''; for j:=1 to i do s:=s+'*'; listbox1.items.add(s); end; end; 2. Vypište všechna prvočísla menší než číslo zadané uživatelem. Vnější cyklus bude zkoumat postupně čísla od 2 do n (ze zadání) a ve vnitřním vždy otestujeme, jde-li o prvočíslo, jestliže ano, vytiskneme ho. Problém jde efektivněji vyřešit použitím Eratosthenova síta, ale k tomu si potřebujeme zpracovávaná čísla pamatovat ve vhodné struktuře – ještě se k němu vrátíme. var i,n,a,odm:integer; begin listbox1.clear; n:=spinedit1.value; listbox1.items.add('prvocisla do '+inttostr(n)); listbox1.items.add('2'); for i:=3 to n do begin odm:=trunc(sqrt(i)); a:=2;

PDF created with pdfFactory trial version www.pdffactory.com

Page 39: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

while (i mod a<>0) and (a<=odm) do inc(a); if a>odm then listbox1.items.add(inttostr(i)); end; end;

Cvičení 1. Řešte první příklad použitím jediného cyklu. 2. Výpis prvočísel, počet zadá uživatel. 3. Tabelace funkce přirozená mocnina 4. Totéž s použitím jediného cyklu. 5. Kolikrát je třeba hodit kostkou, než padne n šestek? (Hody opět zobrazte do listboxu)

Řešení 1. s:=''; for i:=1 to 20 do begin s:=s+'*'; listbox1.items.add(s); end; 2. var i,j,n,o,a:integer; begin listbox1.items.clear; n:= spinedit1.value; j:=2; i:=1; repeat {nalezeni i-teho prvocisla a tisk} o:=trunc(sqrt(j)); a:=2; while (j mod a <>0) and (a<=o)do inc(a); if a>o then begin listbox1.items.add(inttostr(j)); inc(i); end; inc(j); until i>n; end; 3. var i,n,m,k:integer; begin n:=spinedit1.value; listbox1.items.clear; for i:=1 to n do begin m:=1; for k:=1 to i do m:=m*2; listbox1.items.add(inttostr(i)+':'+inttostr(m)); end; end; 4. m:=1; for i:=1 to n do begin

PDF created with pdfFactory trial version www.pdffactory.com

Page 40: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

m:=m*2; listbox1.items.add(inttostr(i)+':'+inttostr(m)); end; 5. var n,i,x:integer; begin randomize; n:=spinedit1.value; listbox1.items.clear; for i:=1 to n do repeat x:=random(6)+1; listbox1.items.add(inttostr(x)); until x=6; end;

14. Procedury – první seznámení V programování často používáme některé akce opakovaně. Potom je výhodné mít možnost je někde nadefinovat a potom jednoduše spustit, aniž bychom je museli v kódu pořád kopírovat. Takovým akcím se říká podprogramy, přesněji, v závislosti na programovacím jazyku procedury, subroutiny nebo funkce. Známe je například jako makra z Microsoft Office, ale vlastně je používáme od začátku i v Delphi. Příklady: Randomize – procedura, která odvodí začátek budoucí posloupnosti náhodných čísel z aktuálního systémového času IntToStr(326) – funkce, která převede číslo na jednotlivé číslice, z nich vytvoří znaky a poskládá řetězec Showmessage(‘Ahoj’) – procedura, zobrazí okno se správou v závorce Form1.Button1Click(Sender: TObject) – procedura, jejiž kód píšeme my a která se spustí, když stiskneme tlačítko, v závorce se nachází jakýsi „Odesílatel typu objekt“, se kterým se důvěrně seznámíme později FloatToStrF(’25.30’,fffixed,2,2) – převedení čísla na řetězec a další údaje v závorce poskytují informace o tom, jak se to má udělat… Máme tedy zkušenosti s používáním (voláním) procedur – zapíše se jejich jméno a do závorky informace o tom s čím co se bude dělat. Obsahu v závorce se říká parametry, jejich prostřednictvím vlastně podprogram komunikuje se svým okolím. Mohou být i procedury bez parametrů (viz randomize), ale ty se opravdu používají jen výjímečně. Definování toho, co procedura dělá se říká deklarace procedury a píše se do deklarační části programu, její volání pak používáme v příkazové části programu nebo podprogramu. (mezi begin a end) Příklad: Umístíme na formulář komponentu Listbox, kterou budeme používat pro výstupy a tlačítko Button, do jehož události Button1Click zapíšeme náš program s definicí a použitím procedur. Příklady budou z algoritmického hlediska velmi jednoduché, budeme se soustředit na psaní podprogramů. Užitečným zvykem je psát to, co poprogramy dělají do komentářů. procedure TForm1.Button1Click(Sender: TObject); {deklarace procedur se píše do deklarační části programu a zde se určí, co bude podprogram dělat} procedure hvezdy1; { vypíše 10 hvězdiček do listboxu} var i:integer;s:string; begin s:=''; for i:=1 to 10 do s:=s+'*'; listbox1.items.add(s); end; procedure hvezdy2(n:integer); { vypíše n hvězdiček do listboxu} var i:integer;s:string; begin s:=''; for i:=1 to n do s:=s+'*';

PDF created with pdfFactory trial version www.pdffactory.com

Page 41: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

listbox1.items.add(s); end; {deklarace hlavního programu a hlavní program} var k:integer; begin listbox1.clear; hvezdy1; {zde se podprogramy používají jako příkazy} hvezdy2(20); k:=spinedit1.value; hvezdy2(k); for k:=1 to 10 do hvezdy2(k); end; Hvezdy1 – procedura vypíše 10 hvězdiček do listboxu. Protože není nijak variabilní, nepotřebuje parametry Pokud bychom potřebovali, aby procedura vytiskla počet hvězdiček podle našeho přání, tento počet použijeme jako její parametr. Hvezdicky2(n:integer) Vypíše n hvězdiček do listboxu. Můžeme ji použít jednak když chceme oddělit nějaká data, ale také kdybychom třeba chtěli zobrazit trojúhelník z hvězdiček: (náš program) * ** *** **** ***** až na n-tém řádku bude n hvězdiček for k:=1 to 10 do hvezdy2(k); – místo formálního parametru je proměnná k, kterou zadá uživatel. Volání procedur: Zatímco v deklaraci procedury vystupují tzv. formální parametry, v jejich volání je třeba použít skutečné parametry, což mohou být proměnné, konstanty či výrazy hlavního programu. Procedura si je dosadí za ty formální a proběhne nad nimi. hvezdy1; hvezdy2(20); – místo formálního parametru je konstanta 20 k:=spinedit1.value; hvezdy2(k); Poznámka: Deklarace hlavního programu a procedur mohou být v zásadě v libovolném pořadí, jen je třeba pamatovat na to, že každý podprogram musí být deklarovaný dřív, než je použitý. (Může ho používat třeba následující podprogram) Všimněte si, že některé proměnné (i) jsou deklarovány uvnitř procedur. Kdybyste je chtěli použít mimo ně, překladač je nezná, jejich platnost je omezená na daný podprogram, mimo něj neexistují. Říká se jim lokální parametry na rozdíl od globálních, deklarovaných v nadřazeném programu nebo podprogramu. Používají se k různým pomocným akcím. Procedury mohou také něco počítat, v následujícím příkladu si ukážeme proceduru na výpočet obsahu trojúhelníka a její použití ve výpočtu obsahu čtyřstěnu. procedure trojuh1(a,b,c:real); Procedura rozhodne, zda trojuhelnik exisuje, pokud ano, vypíše jeho obsah, v opačném případě hlášení. Pokud bychom ji ovšem chtěli použít třeba ve výpočtu povrchu čtyřstěnu, opakované údaje o stěnách vlastně nepotřebujeme, pak by bylo lepší, kdyby procedura předávala obsah trojúhelníka, i informaci jeho o existenci či neexistenci jako výstupní patrametr. procedure trojuh2(a,b,c:real;var S:real;var chyba:boolean); Před výstupním parametrem musí být v deklaraci vyhrazené slovo var, formální parametry různého druhu si při deklaraci oddělují středníky, skutečné parametry při volání čárkami.

PDF created with pdfFactory trial version www.pdffactory.com

Page 42: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

procedure TForm1.Button2Click(Sender: TObject); procedure trojuh1(a,b,c:real); var o,S:real; begin if ((a+b)>c)and ((b+c)>a )and((a+c)>b) then begin o:=(a+b+c)/2; S:=sqrt(o*(o-a)*(o-b)*(o-c)); ShowMessage(FloatToStr(s)); end else ShowMessage('Neni trojuhelnik'); end; procedure trojuh2(a,b,c:real;var S:real;var chyba:boolean); var o:real; begin if ((a+b)>c)and ((b+c)>a )and((a+c)>b) then begin chyba:=false; o:=(a+b+c)/2; S:=sqrt(o*(o-a)*(o-b)*(o-c)); end else chyba:=true; end; var ch1,ch2,ch3,ch4:boolean; S1,S2,S3,S4,Scelk:real; begin trojuh1(spinedit1.value,spinedit2.value,spinedit3.value); trojuh2(spinedit1.value,spinedit2.value,spinedit3.value,S1,ch1); trojuh2(spinedit1.value,spinedit2.value,spinedit4.value,S2,ch2); trojuh2(spinedit1.value,spinedit3.value,spinedit3.value,S3,ch3); trojuh2(spinedit2.value,spinedit3.value,spinedit4.value,S4,ch4); if ch1 or ch2 or ch3 or ch4 then showmessage('blbost') else showmessage(floattostr(s1+s2+s3+s4)); end;

Cvičení Deklarujte procedury v rámci akce ButtonClick a použijte je následujícím způsobem: 1. Procedura znaky – vypíše n znaků ch do listboxu. n i ch jsou její parametry. Použijte ji k výpisu 10 řádků AAAA…AAA BBBB….BBB …. HHHHHHHH Počet písmen zadá uživatel prostřednictvím SpinEditu. 2. Procedura Pozdrav v rámečku z hvězdiček – parametrem je text pozdavu 3. Procedura Kostka se vstupním parametrem velikost hrany a s výstupním parametrem objemem krychle, použijte ji pro výpočet objemu kostek o hranách od 1 do 10 cm. (Výsledky do listboxu)

Řešení 1. procedure TForm1.Button3Click(Sender: TObject); var p:integer;x:char; procedure znaky(n:integer;ch:char); var i:integer;s:string; begin s:=''; for i:=1 to n do s:=s+ch;

PDF created with pdfFactory trial version www.pdffactory.com

Page 43: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

listbox1.items.add(s); end; begin p:=spinedit1.value; for x:='A' to 'H' do znaky(p,x); end; 2. procedure TForm1.Button4Click(Sender: TObject); procedure pozdrav(s:string); var i:integer;pom:string; begin pom:=''; for i:=1 to length(s)+3 do {length(retezec udava delku retezce} pom:=pom+'*'; showmessage(pom+#13+'*'+s+'*'+#13+pom); end; begin pozdrav(Edit1.text); end; 3. procedure TForm1.Button5Click(Sender: TObject); procedure kostka(a:integer;var V:integer); begin v:=a*a*a; end; var i,W:integer; begin listbox1.clear; for i:=1 to 10 do begin kostka(i,W); listbox1.items.add(inttostr(W)+' centiemetrů krychlových'); end; end;

15. Procedury po druhé

Parametry Formální a skutečné Za formální parametry uvedené v hlavičce deklarace procedury se v programu substituují skutečné parametry. Musí si odpovídat co do počtu, typu a pořadí. (Deklarace funguje jako scénář, do kterého při volání procedury dosazujeme konkrétní herce) Parametr hodnota a parametr proměnná Parametr volaný hodnotou: skutečný parametr je něco, co nabývá hodnotu: výraz nebo proměnná. Formální parametr se stane lokální proměnnou procedury, vyhodnotí se skutečný parametr a jeho hodnota se uloží do této lokální proměnné. Výpočet předepsaný procedurou probíhá nad lokálním parametrem, takže se hodí jako vstup. (Původní hodnota skutečného parametru zůstane zachována.) Protože se hodnota skutečného parametru nezmění, nemůže fungovat jako výstup. Parametr volaný odkazem (Při deklarování hlavičky procedury je označen var) Skutečný parametr je výhradně proměnná. Adresa skutečného parametru se spojí se jménem formálního parametru, a všechno se děje nad ním. Původní hodnota se nevratně a trvale změní – užívá se pro výstup. Lokální a globální objekty Lokální objekty mají platnost jen v určitém prostoru, uvnitř podprogramu, ve kterém byly deklarovány. Nepoužívejte globální parametry uvnitř procedur – je to nepřehledné a může být problém s přenositelností takových podprogramů.

PDF created with pdfFactory trial version www.pdffactory.com

Page 44: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Paměť přidělená lokálnímu parametru je po skončení procedury opět uvolněna, lokální parametr mimo oblast své deklarace neexistuje. Pokud chceme používat nějaké objekty (proměnné, ale také podprogramy) ve více akcích, je třeba je deklarovat jako globální. Příklad: Napíšeme proceduru, která pozná dokonalé číslo. (Číslo, které je rovno součtu svých vlastních dělitelů) Abychom ji mohli použít k různým účelům – dejme tomu, že bychom chtěli při stisknutí tlačítka vypsat, zda číslo ve spineditu je dokonalé, případně vypsat všechna dokonalá čísla menší než 100000 do listboxu, budeme ji deklarovat samostatně: (tj. na stejné úrovni jako např. button1.click – kód celého příkladu následuje) procedure dokonal(a:integer;var je:boolean); { je =true, kdyz je cislo dokonale, jinak je false} var d,dok:integer; begin dok:=1; for d:=2 to a div 2 do if a mod d=0 then dok:=dok+d; je:=dok=a; end; procedure TForm1.Button4Click(Sender: TObject); { Rozhodnutí, zda je číslo dokonalé} var x:integer; y:boolean; begin x:=spinedit1.Value; dokonal(x,y); if y then showmessage('ano') else showmessage('ne'); end; procedure TForm1.Button5Click(Sender: TObject); { Výpis dokonalých čísel do 10 000} var i, x:boolean; begin for i:=2 to 10000 do begin dokonal(i,x); if x then listbox1.Items.add(inttostr(i)); end; end; Pokud potřebujeme nějakou proměnnou používat ve více procedurách, musíme ji deklarovat jako globální – prozatím tam, kde je deklarován Form1. Příklad 1. Na formulář umístíme dvě tlačítka a editační políčko. Stisknutí prvního tlačítka uloží do celočíselné proměnné x hodnotu z Editu, druhé tlačítko tuto hodnotu zdvojnásobí a zobrazí zprávu. Vše bude fungovat podle našich představ.pokud x nadeklarujeme globálně. var Form1: TForm1; var x:integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); {var x:integer} begin x:=StrToInt(edit1.Text); end; procedure TForm1.Button2Click(Sender: TObject); {var x:integer;}

PDF created with pdfFactory trial version www.pdffactory.com

Page 45: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

begin x:=2*x; showmessage(inttostr(x)); end; end. Pokud bychom ovšem použili lokální deklaraci (momentálně skrytou v komentářích), zobrazí se nesmyslný výsledek. Příklad 2. Představme si, že máme modrý panel s nápisem budu červený, který po kliknutí zčervená a změní nápis na budu modrý. O stavu panelu sice můžeme rozhodnout z jeho okamžitých vlastností, ale můžeme také použít logickou proměnnou red, která je true když je panel červený. Pak stačí, když při každém kliknutí na panel změní svou hodnotu na negaci. (Je nutno ji ovšem inicializovat, k tomu se obecně hodí procedura formuláře FormCreate) …. Var Form1: TForm1; red:boolean; … procedure TForm1.FormCreate(Sender: TObject); begin red:=False; end; … procedure TForm1.Panel1Click(Sender: TObject); begin red:=not red; if red then begin panel1.Color:=clred; panel1.Caption:='Budu modrý' end else begin panel1.Color:=clblue; panel1.Caption:='Budu èervený' end ; end;

Cvičení: 1. Definujte proceduru mocnina, která vypočítá přirozenou mocninu opakovaným násobením. (Vstupní

parametry základ a exponent, výstupní parametr mocnina.) 2. Použijte ji při : (Každá akce zvláštní tlačítko)

a. Výpočtu obsahu čtverce (vstup z editu) b. Výpočtu objemu krychle (Vstup z editu) c. Výpisu mocnin dvou do Listboxu (od 1 do 10)

3. Použijte globální celočíselnou proměnnou tak, aby tlačítko ve svém názvu zobrazovalo, kolikrát na něj bylo kliknuto.

4. Poskakující tlačítko: Při kliknutí se tlačítko posune o 20 bodů doprava, když dorazí na kraj formuláře, odrazí se a bude putovat zpátky, na levé straně formuláře se opět odrazí atd.

… var klik,posun:integer; Form1: TForm1; implementation {$R *.dfm} procedure mocnina(zak:integer;exp:integer;var vys:integer); var i:integer; begin vys:=1; for i:=1 to exp do vys:=vys*zak;

PDF created with pdfFactory trial version www.pdffactory.com

Page 46: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

end; procedure TForm1.Button1Click(Sender: TObject); var x,V:integer; begin x:=StrToInt(edit1.text); mocnina(x,2,V); showmessage(floattostr(v)); end; procedure TForm1.FormCreate(Sender: TObject); begin Edit1.clear ; klik:=0; {na tlačítko ještě nebylo kliknuto} posun:=20; {posuv druhého tlačítka} end; procedure TForm1.Button2Click(Sender: TObject); var x,V:integer; begin x:=StrToInt(edit1.text); mocnina(x,3,V); showmessage(Inttostr(v)); end; procedure TForm1.Button3Click(Sender: TObject); var m,i:integer; begin listbox1.clear; for i:=1 to 10 do begin mocnina(2,i,m); listbox1.Items.Add(Inttostr(i)+'...'+FloatToStr(m)) ; end; end; procedure TForm1.Button5Click(Sender: TObject); var i,n:integer; x:boolean; begin n:=spinedit1.Value; for i:=2 to n do begin dokonal(i,x); if x then listbox1.Items.add(inttostr(i)); end; end; procedure TForm1.Button7Click(Sender: TObject); begin inc(klik); button7.Caption:='Kliknuls na mì '+IntTostr(klik); end; procedure TForm1.Button6Click(Sender: TObject); begin if (button6.left>form1.Width-button6.width) or (button6.left<0)then posun:=-posun; {když oktaj tlačítka narazí na okraj formuláře, mění se směr posunu} button6.left:=button6.left+posun; end; end.

16. Funkce Pokud je výsledkem procedury jediná vypočítaná hodnota, je její zjišťování maličko nepohodlné. Máme-li například deklarovanou:

PDF created with pdfFactory trial version www.pdffactory.com

Page 47: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Procedure Objem_Kvadru(a,b,c:real; var V:real); Begin V:=a*b*c; End; Použití v programu pak může vypada následovně: Var Objem:real; … Objem_Kvadru(3,4,5,Objem); Showmessage(FloatTostr(Objem)); Také kdybychom chtěli získanou hodnotu použít v dalších výpočtech, musíme nejprve zavolat proceduru a mít předem deklarovanou příslušnou proměnnou. V tomto případě je výhodnější (a bližší práci, na kterou jsem zvyklí z matematiky), použít funkci. Její deklarace: Function Objem_Kvadru(a,b,c:real):real; Begin Objem_Kvadru:=a*b*c; End; Použití: Showmessage(FloatTostr(Objem_Kvadru(3,4,5)); Obecně: Function IdentifikátorFunkce(seznam formálních parametrlů se specifikacemi):typ výsledku; Begin … End; V těle funkce se musí nacházet příkaz, kde je identifikátoru funkce přiřazena hodnota. (Místo jména funkce můžeme použít slovo result.) Hodnotě funkce, (v matematice funkční hodnotě) se říká v programování návratová hodnota. (Funkce vrací hodnotu…) Deklarovanou funkci pak použijeme tak, že zapíšeme její identifikátor tam, kde potřebujeme návratovou hodnotu – tedy například na pravé straně příkazu přiřazení, v příkazech tisku apod. Typ výsledku nesmí být strukturovaný. Delphi procedury a funkce rozlišují méně striktně, než klasický Pascal, některé jiné jazyky vůbec. Příklad 1. Napišme funkci, která převede logickou hodnotu na řetězec a použijme ji v programu, který do Listboxu vypíše definiční tabulku logických operátorů. function BoolToStr(x:boolean):string; begin if x then BoolToStr:='True ' else BoolToStr:='False' end; K výpisu použijeme dvou vnořených cyklů FOR, kdy proměnné a a b budou postupně nabývat všech logickcýh hodnot (tedy False a True) a pro každou kombinaci vypíšeme na řádek listboxu výsledek příslušné logické operace. procedure TForm1.Button1Click(Sender: TObject); var a,b:boolean; s:string; begin s:='a and b a or b a<=>b a xor b'; listbox1.clear; listbox1.items.add(s); for a:=false to true do for b:=false to true do begin s:=BoolTostr(a and b)+' ' + BoolTostr(a or b)+' ' + BoolTostr(a = b)+' '+ BoolTostr(a xor b); Listbox1.items.add(s); end; end; Příklad 2.

PDF created with pdfFactory trial version www.pdffactory.com

Page 48: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Nadeklarujeme logickou funkci, která pozná prvočíslo (bude vracet True, pokud je jejím argumentem prvočíslo, jinak False) Použijeme ji jednak k rozpoznání prvočísla zadaného užiavtelem, jednak k výpisu prvočíselných dvojčat menších než dané číslo. (Prvočíselná dvojčata jsou prvočísla, lišící se o 2. Např. 3,5…5,7…11,13…) function prvok(n:integer):boolean; var odm,d:integer; begin odm:=trunc(sqrt(n)); d:=2; while (n mod d<>0) and (d<=odm) do inc(d); prvok:=(d>odm); end; procedure TForm1.Button3Click(Sender: TObject); begin if prvok(spinedit2.value) then showmessage(‘prvocislo’) else showmessage(‘cislo slozene’); end; Povšimněme si, že protože funkce vrací logickou hodnotu, můžeme její identifikátor použít přímo jako podmínku. (Tato konstrukce se chová stejně jako if prvok(spinedit2.value) =true then… procedure TForm1.Button4Click(Sender: TObject); var i,n:integer; begin listbox1.clear; n:=spinedit2.value; for i:=2 to n-2 do if prvok(i)and prvok(i+2) then listbox1.items.add(IntTostr(i)+','+IntTostr(i+2)) end;

Ještě jednou o parametrech předávaných odkazem Zopakujme si: Když je volán podprogram, zjistí se kterou proměnnou označuje skutečný parametr a na ni pak odkazuje příslušný formální parametr během celého provádění podprogramu. Příklad: (procedura pis není podstatná, jde o předání hodnot celočíselných proměnných uživateli např. procedure pis(x,y,u,z:integer); begin listbox1.items.add(inttostr(x)+ inttostr(y)+ inttostr(u)+ inttostr(z)) end) Var a,b: integer; Procedure P(i:integer; var j:integer); Begin pis(a,b,i,j); i:=3;j:=4; pis(a,b,i,j); a:=5;b:=6; pis(a,b,i,j); i:=7;j:=8; End; …. A:=1; b:=2; p(a,b); pis(a,b,a,b); Sledujme co se děje při provádění programu: A=1, B=2. Při volání procedury P se do I zkopíruje obsah A, parametr J začne odkazovat na proměnnou B. Pis(a,b,i,j) tedy vypíše: 1 2, 1,2 Když se pak do i přiřadí trojka, v a zůstane jednička, změnou hodnoty j na 4 se změní i b. Druhý řádek procedury tedy vypíše: 1 4 3 4 Do a se pak přiřadí 5, do b a tedy i do j 6. Hodnota i se nezměnila. Třetí řádek vypíše: 5 6 3 6 Na závěr se do i přiřadí 7 a do j 8, tím se také změní hodnota b. Příkaz pis(a,b) tedy vypíše 5 8 5 8

PDF created with pdfFactory trial version www.pdffactory.com

Page 49: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Cvičení 1) Deklarujte funkci NSD, vstupem budou dvě celá čísla, výstupem jejich největší společný dělitel. Použijte ji

při: Krácení zlomku na základní tvar (čitatele a jmenovatele zadá uživatel) a) Výpočtu nejmenšího společného násobku dvou čísel, která opět zadá uživatel

2) Deklarujte funkci, která pro vstupující celé číslo vrací jeho ciferný součet. Použijte ji při: a) Výpisu ciferného součtu čísla zadaného uživatelem b) Řešení následujícího problému: Uživatel zadá jistý interval v celých číslech a program vypíše všechna

čísla, z daného intervalu, která mají určitý ciferný součet, opět zadaný uživatelem. Řešení: 1. function nsd(a,b:integer):integer; begin while a<>b do if a>b then a:=a-b else b:=b-a; nsd:=a; end; procedure TForm1.Button2Click(Sender: TObject); var c,j,d:integer; begin c:=spinedit1.value; j:=spinedit2.value; d:=nsd(c,j); c:=c div d; j:=j div d; showmessage(Inttostr(c)+'/'+IntTostr(j)); end; procedure TForm1.Button3Click(Sender: TObject); var nsn,c,j:integer; begin c:=spinedit1.value; j:=spinedit2.value; nsn:=c*j div nsd(c,j); showmessage(inttostr(nsn)); end; function cs(n:integer):integer; var s:integer; begin s:=0; repeat s:=s+n mod 10; n:=n div 10; until n=0; cs:=s; end; procedure TForm1.Button5Click(Sender: TObject); begin showmessage(IntTostr(cs(spinedit3.value))); end; procedure TForm1.Button6Click(Sender: TObject); var i,a,b,c:integer; begin listbox1.clear; a:=spinedit1.value; b:=spinedit2.value; c:=spinedit3.value; for i:=a to b do if cs(i)=c then listbox1.items.add(inttostr(i)); end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 50: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

17. Programové jednotky I když se snažíme psát své programy přehledně, používáme podprogramy, komentujeme, odsazujeme atp., v delších programech snadno ztratíme orientaci. Bude tedy vhodné kód nějakým způsobem rozčlenit. Kromě toho – když už jednou naprogramujeme nějaké procedury a funkce, budeme je chtít používat bez zbytečného kopírování. A co když budeme pracovat v týmu a potřebujeme si nějak rozdělit práci? Všechny uvedené problémy řeší používání programových jednotek (unitů). Unit je zvláštní soubor, který obsahuje datové typy, proměnné, procedury a funkce, které spolu zpravidla nějak souvisí a můžeme je používat v dalších programech. Unit může obsahovat i příkazovou část, která je volána hned po spuštění programu, který unit obsahuje. Výhody: – program může být rozčleněn na samostatně přeložitelné součásti

– knihovny procedur pro nejrůznější programy – zvýšení univerzálnosti procedur a funkcí – snadnější týmová práce – zvýší se čitelnost programu – samostatný překlad jednotek urychluje konečný překlad – obsah jednotky lze skrýt před okolím a povolit pouze používání určitých objektů a metod.

Kvalifikovaný identifikátor: odkazujeme-li se na objekt jiného unitu, můžeme k odlišení použít zápis: Jméno_unitu.Jméno_objektu

Struktura unitu: Unit Jméno; (hlavička) Interface – rozhraní deklarace přístupné programům nebo jiným jednotkám. Pokud používá jednotka objekty jiných jednotek, je třeba je umístit do klauzule uses hned za Interface Implementation lokální deklarace jednotky, vlastní definování procedur a funkcí end. (V případě příkazové čási begin – příkazová část – end.) Zdrojový soubor unitu má příponu pas Poznámka: Lze užít inicializační část – Initialization – která se provede před prvním použitím jednotky. (nastavení počátečních hodnot proměnných apod. Spolu s ní lze zařadit také úklidovou část – Finalization – ta se provádí těsně před skončením programu. (uvolnění alokované paměti apod.) Vytvoření nové jednotky File/New/Unit Delphi vytvoří Unit2 s následující strukturou: unit Unit2; interface implementation end. A stačí dopsat kód. Přidání a odstranění existující jednotky: Project /Add to Project Zásada: jméno unitu musí být v klauzuli USES každé jednotky, která ji používá Project/Remove from Project Správa jednotek projektu – View/Project Manager Použití unitu: Stačí ho dopsat za klíčové slovo uses v deklarační části programu a už se vším,co nabízí ve svém interface můžeme pracovat tak, jako bychom to měli deklarováno přímo v tomto programu. Kruhová reference V části interface jedné jednotky nesmí být uvedena jednotka, která odkazuje zpátky na první jednotku. Řešení: v jedné jednotce přesuneme připojení (klauzuli USES) do implementační části. Příklad Unit3 deklaruje funkci přirozená mocnina, kterou pak voláme v Unitu2. unit unit3; interface

PDF created with pdfFactory trial version www.pdffactory.com

Page 51: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

function moc(n,k:integer):integer; implementation function moc(n,k:integer):integer; var i,p:integer; begin p:=1; for i:=1 to k do p:=p*n moc:=p; end; end. Použití: uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin, unit3, ExtCtrls, Buttons; …. procedure TForm1.BitBtn1Click(Sender: TObject); var a,b:integer; begin a:=spinedit1.value; b:=spinedit2.value; showmessage(IntTostr(moc(a,b))

Unit1 V Delphi má každý formulář vlastní jednotku. Prohlédněme si teď trošku informovaněji UNIT1, který Delphi otvírají s vytvořením prvního formuláře aplikace. unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} end. V sekci interface najdeme v klauzuli uses seznam jednotek, které potřebujeme, abychom mohli pracovat s komponentami, (např. Graphics potřebujeme pro práci s barvami, Dialogs pro užití procedury Showmessage…) definici typu formuláře (i k té se zanedlouho propracujeme), deklaraci proměnné typu formulář a implementační část. Pokud vložíme na formulář komponentu a použijeme nějakou její událost, přibude tato událost jednak v sekci interface u formuláře, jednak se objeví jako prázdná procedura v implementační části, do které zapisujeme naše kódy.

Cvičení: Připravte si unit na práci s funkcemi – bude nabízet reálnou mocninu, logaritmus o libovolném základu, a alespoň 5 geometrických vzorců. Případy, kdy funkce nejsou definovány ošetřete přímo během zadávání hodnot, k opravdu funkčnímu zabezpečení programu bychom potřebovali mechanismus výjimek, se kterým se zanedlouho seznámíme. Použijte ho v programu, kde si uživatel typ výpočtu vybere pomocí komponenty radiogroup.

PDF created with pdfFactory trial version www.pdffactory.com

Page 52: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Nastavte změny popisků u editačních políček, aby odpovídaly řešenému problému. Využijte vlastnosti visible (true, false) Řešení unit Unit2; interface function realmoc(z,e:real):real; function log(z,x:real):real; {z-yaklad,x-argument} function koule(x:real):real; implementation function realmoc(z,e:real):real; begin realmoc:=exp(ln(z)*e); end; function log(z,x:real):real; begin log:=ln(x)/ln(z); end; function koule(x:real):real; begin koule:=pi*x*x*x; end; end. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Unit2; ... procedure TForm1.Button1Click(Sender: TObject); var x,y,z:real; begin case radiogroup1.itemindex of 0: begin x:=strtofloat(edit1.text); y:=strtofloat(edit2.text); if x<=0 then begin showmessage('nedef'); edit1.text:='0'; edit2.text:='0'; edit1.setfocus; end else showmessage(floattostrf(realmoc(x,y),fffixed,10,3)) end; 1: begin x:=strtofloat(edit1.text); y:=strtofloat(edit2.text); if (x<=0)or (x=1) or (y<=0) then begin showmessage('nedef'); edit1.text:='0'; edit2.text:='0'; edit1.setfocus; end else showmessage(floattostrf(log(x,y),fffixed,10,3)) end; 2: begin x:=strtofloat(edit1.text); if x<0 then

PDF created with pdfFactory trial version www.pdffactory.com

Page 53: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

begin showmessage('nedef'); edit1.text:='0'; edit1.setfocus; end else showmessage(floattostrf(koule(x),fffixed,10,3)) end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin edit1.Text:='0'; edit2.Text:='0'; end; procedure TForm1.RadioGroup1Click(Sender: TObject); var x,y,z:real; begin case radiogroup1.itemindex of 0: begin label1.Caption:='zaklad'; label2.Caption:='exponent'; edit2.Visible:=true; x:=strtofloat(edit1.text); y:=strtofloat(edit2.text); end; 1: begin label1.Caption:='zaklad'; label2.Caption:='log.cislo'; edit2.Visible:=true; x:=strtofloat(edit1.text); y:=strtofloat(edit2.text); end; 2: begin label1.Caption:='polomer'; label2.caption:=''; x:=strtofloat(edit1.text); edit2.visible:=FALSE; end; end; end;

18. Opakování Připravte si nejprve unit s potřebnými procedurami a funkcemi a použijte ho při řešení problémů.

Podprogramy: 1. Funkce Vypis: Vstupní parametry: Řetězec a celé číslo Funkční hodnota: řetězec zleva doplněný mezerami, aby měl délku určenou číselným parametrem. Pokud je délka vstupního řetězce větší než číslo, nezmění se. 2. Funkce JePythag: Vstupní parametry: tři celá kladná čísla Funkční hodnota: True, pokud čísla splňují Pythagorovu větu, jinak False. 3. Pro srovnání čísel použijte proceduru bublej, která má tři vstupně-výstupní parametry a po jejím proběhnutí bude ve třetím z nich maximum trojice. (Použitá metoda porovná nejprve první dvě čísla, pokud je druhé menší, vymění je a totéž provede pro druhá dvě čísla.)

PDF created with pdfFactory trial version www.pdffactory.com

Page 54: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

4. Funkce Kvadrat: Vstupní parametry: Dvě kladná celá čísla Funkční hodnota: součet druhých mocnin těchto čísel. 5. Funkce Aspon3: Vstupní parametr: čtyřciferné celé číslo Funkční hodnota: True, pokud má spoń tři cifry stejné, jinak False

Problémy: 1. Zobrazte do listboxu tabulku malé násobilky, pro zarovnání čísel pod sebe použijte funkci Vypis. (Nezapomeňte u listboxu nastavit v Properties neproporcionální font, například Courier. 2. Vstupem jsou tři kladná celá čísla ze spineditů, vypište, zda mohou být stranami pravoúhlého trojúhelníka. (Využijte funkci JePythag, předpokládejte vstup v libovolném pořadí a pro potřebné srovnání trojice proceduru Bublej) 3. Nalezněte všechny pythagorejské trojúhelníky (pravoúhlé trojúhelníky s celočíselnými délkami stran), jejichž všechny tři strany jsou jsou menší, než dané celé N. Můžete použít tři vnořené cykly pro a,b,c a funkci JePythag, mnohem efektivnější bude ale způsob, kdy použijete jen dva cykly pro odvěsny a přeponu vždy dopočítáte funkcí Kvadrat. 4. Spočítejte a vytiskněte všechna čtyřciferná čísla, která obsahují aspoň tři stejné cifry. Vyzkoušejte variantu s funkcí Aspon3 a průchodem všech čtyřciferných čísel a porovnejte ji (s opět podstatně rychlejším způsobem) kdy potřebná čísla přímo vytvoříte a přitom zjistíte jejich počet.

Řešení: unit Unit2; interface uses SysUtils; function Vypis(s:string;d:integer):string; function JePythag(a,b,c:integer):boolean; procedure vymen(var a,b:integer); procedure bublej(var a,b,c:integer); function kvadrat(a,b:integer):integer; function aspon3(x:integer):boolean; implementation function Vypis(s:string;d:integer):string; var i,l:integer; begin if length(s)<d {length(s) vraci delku retezce} then begin l:=length(s); for i:=1 to d-l do s:=' '+s; end; result:=s; end; procedure vymen(var a,b:integer); var p:integer; begin p:=a;a:=b;b:=p; end; procedure bublej(var a,b,c:integer); begin if a>b then vymen(a,b); if b>c then vymen(b,c); end; function JePythag(a,b,c:integer):boolean; begin bublej(a,b,c); result:=sqr(a)+sqr(b)=sqr(c); end; function kvadrat(a,b:integer):integer; begin result:=sqr(a)+sqr(b) end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 55: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

function aspon3(x:integer):boolean; var a,b,c,d:integer; begin aspon3:=false; d:=x mod 10; x:=x div 10; c:=x mod 10; x:=x div 10; b:=x mod 10; x:=x div 10; a:=x mod 10; aspon3:=(a=b)and(b=c){stejne prvni tri nebo vsechny} or (a=b)and(b=d){stejne prvni,druha,ctvrta nebo vsechny} or (a=c)and(c=d){stejne prvni,treti,ctvrta nebo vsechny} or (c=b)and(b=d);{stejne ,druha,treti ctvrta nebo vsechny} end; end. procedure TForm1.Button1Click(Sender: TObject); {mala nasobilka} var s:string; i,j:integer; begin for i:=1 to 9 do begin s:=''; for j:=1 to 9 do s:=s+vypis(inttostr(i*j),3); listbox1.items.add(s) end; procedure TForm1.Button3Click(Sender: TObject); {vypis pythagorejských cisel} var a,b,c,n:integer; begin n:=StrToInt(edit1.Text); for a:=1 to n do for b:=a to n do for c:= b to n do {pri tomto reseni by nebylo nutne ve funkvi JePythag uzivat bublani, protože c je urcite nejvetsi} if JePythag(a,b,c) then listbox1.items.add( IntTostr(a)+' '+IntTostr(b)+' '+ IntTostr(c)); end; procedure TForm1.Button4Click(Sender: TObject); {jsou na vstupu pzthagorejska cisla?} var a,b,c:integer; begin a:=spinedit1.Value; b:=spinedit2.Value; c:=spinedit3.Value; if JePythag(a,b,c) then showmessage('ano') else showmessage('ne') end; procedure TForm1.Button5Click(Sender: TObject); {efektivnejsi vypis Pythagorejskych cisel} var a,b,kvac,n:integer; begin n:=StrToInt(edit1.Text);

PDF created with pdfFactory trial version www.pdffactory.com

Page 56: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

for a:=1 to n do for b:=a to n do begin kvac:=kvadrat(a,b); if (trunc(sqrt(kvac))=sqrt(kvac))and (sqrt(kvac)<=n) then listbox1.items.add( IntTostr(a)+' '+IntTostr(b)+' '+ IntTostr(trunc(sqrt(kvac)))); end; end; procedure TForm1.Button6Click(Sender: TObject); {vypis čtyrciferných cisel s aspon ctyrmi stejnymi ciframi postupnym proverovanim} var xx,p:integer; begin p:=0; for xx:=1000 to 9999 do if aspon3(xx) then begin listbox1.items.add(IntTostr(xx)); inc(p); end; showmessage(inttostr(p)); end; procedure TForm1.Button7Click(Sender: TObject); {efektivnejsi vypis} var a,b,c,d,x,p:integer; begin p:=0; {stejne posledni tri cifry nebo vsechny} for a:=1 to 9 do for b:=0 to 9 do begin x:=1000*a+100*b+10*b+b; listbox1.Items.add(inttostr(x)); inc(p); end; {stejne prvni tri cifry} for a:=1 to 9 do for b:=0 to 9 do begin if a<>b then {aby se nepridavaly vsechny stejne znova} begin x:=1000*a+100*a+10*a+b; listbox1.Items.add(inttostr(x)); inc(p); end; end; {stejna prvni, druha a ctvrta} for a:=1 to 9 do for b:=0 to 9 do begin if a<>b then begin x:=1000*a+100*a+10*b+a; listbox1.Items.add(inttostr(x)); inc(p); end; end; {stejna prvni, treti a ctvrta} for a:=1 to 9 do for b:=0 to 9 do begin if a<>b then begin x:=1000*a+100*b+10*a+a; listbox1.Items.add(inttostr(x)); inc(p);

PDF created with pdfFactory trial version www.pdffactory.com

Page 57: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

end; end; showmessage(inttostr(p)); end;

19. Datový typ pole Strukturované typy Dosud jsme se zabývali typy, jejichž hodnoty byly nedělitelné. Někdy si ovšem potřebujeme pamatovat víc hodnot najednou a umět s nimi pracovat jako s celkem. (Příklad: Získáme měřením sadu hodnot – třeba délek nějakého předmětu a pokud chceme zjistit, jak bylo toto měření přesné, potřebujeme vypočítat odchylky jednotlivých hodnot od průměru. K tomu si ovšem musíme pamatovat všechny hodnoty i jejich pořadí) Objekty, které jsou tvořeny skupinami dalších hodnot, se nazývají strukturované. (Pole, záznam, množina, soubor, objekt)

Pole Pole je homogenní struktura, skládající se ze složek stejného typu, které rozlišujeme pomocí indexů. (Vlastně pořadové číslo prvku v poli) Delphi umožňují pracovat s polem statickým (v této kapitole), jehož velikost je dána v okamžiku deklarace a dynamickým (za chviličku). Definice statického pole type JménoTypu = arrray[typ indexů] of TypPrvků Příklady: const n=20; type cisla=array[1..n] of integer; slova=array[1..100]of string; cetnost=array[char] of integer; mereni=array[1..n]of real; kod=array[char]of char; (Poslední pole se dá použít jako kódovací tabulka) Typ indexů musí být ordinální, často se používá interval. Při deklaraci se vyhrazuje paměť – tedy zde např. 20*4B=80B pro objekt typu cisla. Typ prvků může být libovolný, rovněž strukturovaný. Jako meze intervalů v indexech jsou ideální konstanty, v rozsáhlých programech změníme rozměr pole pohodlně a bezpečně jediným zápisem. Práce s proměnnou typu pole var a,b: cisla; cet:cetnost; Přepokládejme, že proměnná a obsahuje tato čísla: 2 1 3 4 5 6 7 8 9 0 2 4 5 6 7 8 5 8 9 4 pak a[1]=2, a[3]=3…a[10]=4 a[1]:=a[1]+1…změní hodnotu prvního prvku na 3. I když pro pole téhož typu můžeme použít přiřazovací příkaz (a:=b), v dalších případech zpracováváme pole po prvcích. (položkách) For i:=1 to n do a[i]:=I; vytvoří pole 1 2 … 10 For i:=1 to n do listbox1.items.add(IntTostr(a[i])); výpis pole do listboxu For ch:=’A’ to ‘Z’ do cet[ch]:=0; vynulování všech položek pole V indexech prvků mohou být i výrazy. (a[2*i-1] ) Funkce low(a) a high(a) vracejí nejmenší hodnotu indexu – zde tedy 1 a 20. Deklarace s anonymním typem var x:array[1..n] of integer; Ušetří nám sice práci se definicí typu, ale takové pole jednak nelze použít jako parametr podprogramů, jednak nemůžete napsat příkaz x:=a; protože překladač je nepovažuje za tentýž typ.

Příklady pro vstup budeme zatím používat generátor náhodných čísel.

PDF created with pdfFactory trial version www.pdffactory.com

Page 58: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

1. Vygenerujte pole náhodných čísel, vytiskněte ho do Listboxu a zobrazte položku pole, jejíž index zadá uživatel do Spineditu. var i:integer; begin for i:=1 to n do a[i]:=random(20); end; var i:integer; begin listbox1.clear; for i:=1 to n do listbox1.items.add(IntToStr(a[i])); end; … showmessage(Inttostr(a[spinedit1.value])); Prvky pole bychom mohli tisknout už během generování, ale protože se nimbuse hodit zobrazovat pole po různých dalších úpravách, bude výhodné obě akce oddělit. 2. Vyměňte dva prvky pole, jejichž indexy zadá uživatel Proceduru na výměnu dvou čísel nadeklarujeme globálně, abychom ji mohli používat v dalších příkladech. procedure vymen(var x,y:integer); var p:integer; begin p:=x; x:=y; y:=p; end; procedure TForm1.Button9Click(Sender: TObject); var i,j:integer; begin i:=spinedit1.value; j:=spinedit2.value; vymen(a[i],a[j]) end;

3. Vygenerujte pole náhodných čísel, vytiskněte ho do Listboxu, vypočítejte aritmetický průměr, odchylky od něj a ty vytiskněte do dalšího listboxu. function prum(aa:cisla):real; var s,i:integer; begin s:=0; for i:=1 to n do s:=s+aa[i]; prum:=s/n; end; procedure TForm1.Button7Click(Sender: TObject); begin showmessage(FloatToStrF(prum(a),fffixed,6,2)) end; procedure TForm1.Button8Click(Sender: TObject); var i:integer; p:real; begin p:=prum(a); for i:=1 to n do listbox2.Items.Add(Floattostr(a[i]-p)) end;

Cvičení 1. Vytiskněte počet trojek ve vašem poli. 2. Zdvojnásobte položky pole a opět ho vytiskněte.

PDF created with pdfFactory trial version www.pdffactory.com

Page 59: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

3. Nalezněte nejmenší prvek (je-li jich víc, nalezněte ten s nejmenším indexem) a vyměňte ho s prvním prvkem pole. Upravené pole opět vytiskněte. 4. Otočte pole tak, aby první prvek byl poslední… Upravené pole opět vytiskněte.

Řešení 1. pt:=0; for i:=1 to n do if a[i]=3 then inc(pt); showmessage(inttostr(pt)); 2. for i:=1 to n do a[i]:=2*a[i]; 3. var i,min,imin:integer; {imin je index prvniho nalezeneho minima} begin min:=maxint; imin:=0; for i:=1 to n do if a[i]<min then begin min:=a[i]; imin:=i; end; showmessage(inttostr(min)); vymen(a[1],a[imin]); end; 4. var i,p:integer; begin p:=n div 2; for i:=1 to p do vymen(a[i],a[n-i+1]); end;

20. Pole – vstup dat od uživatele, další příklady při práci s polem je výhodné mít možnost zobrazovaná data prohlédnout – proto v následujících příkladech použijeme vždy komponentu Listbox, přes který je také budeme načítat do statických polí. Data uložená v listboxu jsou typu TStrings, což je objekt se spoustou metod (Zatím jsem používali metodu items.add(S:string) pro přidání řetězce), jehož datovou část tvoří dynamické pole řetězců (na rozdíl od statického nemá délku omezenou deklarací) K jednotlivým řádkům se dostaneme přes jejich index – items[i], první řádek má vždy index nula. V dalších příkladech budeme používat pole řetězců: const n=10; type slova=array[1..n] of string; deklarované v části interface Unit1. Na formulář si nachystáme dva Listboxy a Opendialog z Dialogs na paletě komponent. Postupně budeme přidávat tlačítka pro události. Procedura pro zobrazení statického pole do listboxu: procedure ukaz(a:pole;l:Tlistbox); var i:integer; begin l.clear; for i:=1 to n do l.items.add(a[i]); end;

Vstup dat z připraveného listboxu: Položky připravíme do Listboxu v době návrhu programu pomocí StringList editoru (Vyvolá se klepnutím na tlačítko se třemi tečkami u vlastnosti Items v inspektoru objektů) procedure TForm1.Button1Click(Sender: TObject); var i:integer;

PDF created with pdfFactory trial version www.pdffactory.com

Page 60: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

begin if listbox1.items.count<N {aby stačila data} then showmessage('malo dat') else begin for i:=1 to n do b[i]:=listbox1.items[i-1]; ukaz(b,listbox2); end; end; Vstup dat z editačního políčka Do vstupního listboxu můžeme data také přidávat – například při stisknutí klávesy Enter v editačním políčku a pak je použít. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if key=#13 then begin listbox1.items.add(edit1.Text); edit1.clear; edit1.setfocus; {políčko je práydné a je v něm kuryor – čeká na další vstup} end; end;

Vstup dat z textového souboru Data si můžeme připravit do textového souboru například v Poznámkovém bloku a načíst je do Listboxu s pomocí klasického okenního dialogu pro otevření souboru – komponenta Opendialog. procedure TForm1.Button2Click(Sender: TObject); begin if Opendialog1.execute {je-li vvykonán dialog} then listbox1.items.loadFromFile(OPendialog1.filename); {načteme obsah vybraného textového souboru do listboxu1.} end; Některé vlastnosti OpenDialogu: InitialDir – výchozí složka Filter – Texty|*.txt – druh zobrazovaných souborů v dialogovém okně, pohodlně se nastaví příslušným editorem Title – text na titulní liště Příklad: Napište proceduru, která na jediný průchod najde současně největší a nejmenší číslo v poli reálných čísel. Vyzkoušejte ji na předem připravené údaje v textovém souboru. procedure TForm1.Button3Click(Sender: TObject); type cisla=array[1..n]of integer; procedure minimax(a:cisla;var min,max:integer); var i:integer; begin min:=maxint; max:=-maxint; {porovname vzdy dva sousedy vzajemne, vetsiho z nich s maximem a mensiho s minimem} for i:=1 to n-1 do if a[i]<a[+1] then begin if a[i]<min then min:=a[i]; if a[i+1]>max then max:=a[i]; end else begin if a[i]>max then max:=a[i]; if a[i+1]<min then min:=a[i+1]; end; if odd(n) {pokud nam zbylo posledni cislo} then if a[n]>max then max:=a[n] else

PDF created with pdfFactory trial version www.pdffactory.com

Page 61: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

if a[n]<min then min:=a[n]; end; var b:cisla;mi,ma,i:integer; begin if opendialog1.execute then begin listbox1.Items.LoadFromFile(opendialog1.filename); for i:=1 to n do b[i]:=strtoint(listbox1.Items[i-1]); minimax(b,ma,mi); showmessage(inttostr(ma)+' '+inttostr(mi)); end; end;

Cvičení 1. Pracujte s polem řetězců, které si připravíte do Listboxu při návrhu programu. Posuňte nejdelší řetězec na konec pole postupným probubláváním – procházejte pole po dvojicích a je-li kratší slovo před delším, vyměňte je. 2. Připravte si dva textové soubory, do jednoho události, do druhého letopočty. Zobrazte je do dvou listboxů, pokud uživatel zadá do editačního políčka letopočet, zobrazí se mu v dalším políčku událost. 3. Doplňte předchozí příklad zkoušením – na stisknutí tlačítka se náhodně vybere událost a uživatel k ní má přiřadit letopočet.

Řešení 1. procedure TForm1.Button4Click(Sender: TObject); var i:integer; procedure vymen(var a,c:string); var p:string; begin p:=a;a:=c;c:=p; end; begin for i:=1 to n-1 do if length(b[i])>length(b[i+1]) then vymen(b[i],b[i+1]); ukaz(b,listbox2); end; 2. var Form1: TForm1; …akce,roky:pole,; … procedure TForm1.Button2Click(Sender: TObject); {nacteni dat} var i:integer; begin if Opendialog1.execute then listbox1.items.loadFromFile(OPendialog1.filename); if Opendialog1.execute then listbox2.items.loadFromFile(OPendialog1.filename); for i:=1 to n do begin akce[i]:=listbox2.items[i-1]; roky[i]:= listbox1.items[i-1]; {oba soubory nacteme najednou} end; end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 62: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

procedure TForm1.Button5Click(Sender: TObject); var i:integer; begin i:=1; while (i<=n) and (roky[i]<>edit1.Text)do {vyhledame index letopoctu} inc(i); if i>n then showmessage('nemame') else edit2.Text:=akce[i];{zobrazime událost} end; procedure TForm1.Button6Click(Sender: TObject); begin randomize; k:=random(n)+1; {k je deklarovana globalne, aby se dala pouzit i v nasledujici procedure} edit1.Text:=roky[k]; edit2.clear; edit2.setfocus; {nahodny letopocet} end; procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char); {když uživatel odesle Enterem slovo v Edit2, provede se kontrola} var i:integer; begin if key=#13 then begin if edit2.text=akce[k] then showmessage('spravne') else showmessage('spravne ma byt '+akce[k]); edit1.clear; edit2.clear; edit2.SetFocus; end; end;

21. Vyhledávání v poli Velmi častý problém, se kterým se v praxi můžeme setkat je zjistit, zda se v poli údajů vyskytuje nějaký prvek, případně kde je. (Například chceme editovat nebo odstranit určitý záznam v databázi). Pro tento účel existují nejen různé algoritmy, ale byly také vytvořeny zajímavé datové struktury jako vyhledávací sitě, binární vyhledávací stromy apod. Za daných okolností bývá určitý způsob vyhledávání, případně použití určitého druhu dat vhodnější než jiný, to je třeba zvážit podle konkrétního problému. Efektivnost vyhledávacích algoritmů většinou poměřujeme počtem operací srovnání, které algoritmus potřebuje. Počet prvků dále uvažujeme n, hledáme v poli a, vyhledávaný prvek bude x. Funkce, které budme psát mohou vracet true nebo false („Našli moji rádcové princezničku?“), případně index prvního výskytu.

Sekvenční vyhledávání v nesetříděné struktuře Můžeme projít celé pole cyklem for: function jetam1(a:pole;x:integer):integer; {vraci posledni index vyskytu nebo 0 kdyz neni} var i,pom:integer; begin pom:=0; for i:=1 to n do if a[i]=x then pom:=i; jetam1:=pom;

PDF created with pdfFactory trial version www.pdffactory.com

Page 63: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

end; Tento způsob ovšem není příliš efektivní pokud byste chtěli první výskyt prvku – pak je při jeho objevení lepší skončit. Procházíme celá data, pokud vyhledávaný prvek nalezneme, uknočíme vyhledávání. Pokud bychom použili po procházení složenou podmínku: While (a[i]<>x) and (i<=n){ dosud nenalezen hledaný prvek a ještě nejsem na konci} může vzniknout problém když prvek nenajdeme – naposled se bude vyhodnocovat a[n+1] a překročíme rozsah indexů. Problém lze vyřešit pomocnou logickou proměnnou, (další procedura), tento algoritmus se dá dobře používat i v dalších datových strukturách. Složitost v nejhorším případě n – pokud prvek v poli není a je nutné ho projít celé function Jetam(b:pole;x:integer):boolean; var nasel:boolean;i:integer; begin i:=1; nasel:=false; while not nasel and(i<=n) do if b[i]=x then nasel:=true else inc(i); jetam:=nasel; end;

Zarážka Vyhledávaný prvek se umístí na konec pole, takže není nutné testovat první podmínku. Složitost je asi o 20% lepší, v nejhorším případě stejná. function zarazka (b:pole;x:integer):boolean; {pole ovšem na zacatku musite deklarovat vetsi array[1..n+1] of integer} var i:integer; begin b[n+1]:=x; i:=1; while b[i]<>x do inc(i); zarazka:=(i<=n) end;

Binární vyhledávání v setříděné posloupnosti Prvek porovnáme s prostředním, je-li menší, opakujeme hledání v první polovině struktury, je-li větší, ve druhé. Při prvním porovnání tak vyřadíme polovinu prvků, při druhém čtvrtinu…v nejhorším případě odpovídá počet porovnání:log2n Tento způsob je sice nejefektivnější, ale setříděná posloupnost se příliš nehodí pro udržování. (Například při vkládání na určitou pozici je zase nezbytné zbytek posloupnosti odsunout sekvenčním způsobem.) function binvyh(b:pole;x:integer):boolean; var i,j,s:integer; begin i:=1; j:=n; repeat s:=(i+j) div 2; {index prostredniho prvku v akyalni casti pole} if x>=b[s] then i:=s+1; {jdeme doprava} if x<=b[s] then j:=s-1; {jdeme doleva} until i>j; binvyh:=(x=b[s]) end;

Cvičení 1. Načtěte pole čísel z textového souboru a implementujte vyhledávací funkce.

Dále:

PDF created with pdfFactory trial version www.pdffactory.com

Page 64: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

2. Upravte funkci s FOR cyklem tak, aby vracela první výskyt prvku. 3. Vygenerujte setříděné pole náhodných čísel a vyzkoušejte algoritmus binárního vyhledávání. Řešení Type … pole =array[1..n+1]of integer; var Form1: TForm1; a:pole; … function jetam5(a:pole;x:integer):integer; {vraci prvni index vyskytu nebo 0 kdyz neni - nejrychlejsi reseni s unikem z cyklu neodpovida pravidlum strukturovaneho programovani} var i,pom:integer; begin pom:=0; for i:=1 to n do if a[i]=x then begin pom:=i; break; end; jetam5:=pom; end; procedure TForm1.Button2Click(Sender: TObject); {vyvolani libovolne vyhledvaci funkce} begin if jetam5…5(a,spinedit1.value)<>0 then showmessage('Našli na '+Inttostr(jetam55(a,spinedit1.value))) else showmessage('Nenašli') end; procedure TForm1.Button4Click(Sender: TObject); {generovani setrideneho pole} var i,d:integer; begin a[1]:=0; listbox1.items.add(inttostr(a[1])); for i:=2 to n do begin d:=random(5); a[i]:=a[i-1]+d; listbox1.items.add(inttostr(a[i])); end; end;

22. Třídění aneb jak ukládat data, aby k nim byl snadný přístup Problém: je dáno pole A[1]..A[n] nějakých prvků (v praxi tvorby informačních systémů nejčastěji záznamů databází) Chceme, aby po proběhnutí třídícího algoritmu platilo: a[1]<=a[2]<=… a[n] U záznamů třídíme podle jedné (v případě rovnosti podle další…) položky, které se říká třídící klíč.

Několik algoritmů a jejich složitost (opět porovnáváme počet srovnávacích operací, ve všech programových ukázkách třídíme pole, které má n celých čísel)

PDF created with pdfFactory trial version www.pdffactory.com

Page 65: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Vsouvání a[1]<=a[2]<=…a[k] a[k+1] ? a[k+2]…? a[n] První část pole je setříděna, chceme zařadit další prvek. Začneme ho porovnávat se zařazenými prvky, když zjistíme místo, kam patří, zbytek odsuneme o jedno místo doprava. Složitost v nejhorším případě (opačně setříděné pole): n+n-1+…3+2+1 = n*(n-1)/2 ~ n2 – kvadratický algoritmus Nejlepší případ – setříděná posloupnost, složitost ~ n. (Na umístění jednoho prvku potřebujeme jedno porovnání) var i,j,x:integer; begin p[0]:=-maxint; for i:= 2 to n do begin j:=i; x:=p[i]; {dosud nezařazený prvek} while p[j-1]>x do begin p[j]:=p[j-1]; dec(j); end; p[j]:=x; end; end; Přímý výběr Nejprve najdeme minimum, vyměníme ho s prvním prvkem a pakpokračujeme dál: yabýváme se vždy úsekem pole od i do n, vyhledáme v něm minimum a vyměníme ho s i-tým prvkem. Složitost je opět kvadratická, navíc nerozlišuje nejlepší a nejhorší případ. (Rychlost při spuštění na počítači vyplývá z toho, že údaje pro for-cykly se připravují do cache procesoru, čímž se zpracovámí zrychlí) var i,j,imin:integer; begin for i:=1 to n-1 do begin imin:=i; for j:=i to n do if p[j]<p[imin] then imin:=j; vymen(p[i], p[imin]); end; end; Třídění probubláváním Procházíme pole po dvojicích a je-li větší prvek před menším, vyměníme je. Po prvním průchodu se dostane největší prvek nakonec. Po druhém průchodu můžeme podobně zařadit na předposlední místo druhý největší prvek atd. Vylepšení: Při každém průchodu evidujeme, zda jsem vyměňovali a algoritmus ukončíme, když se nevyměňovalo. (setříděné pole) var i,j:integer; begin for i:=n downto 2 do {kam az bublame} for j:=1 to i-1 do {bublani} if p[j]>p[j+1] then vymen (p[j],p[j+1]); end; var i:integer;b:boolean; begin repeat b:=false; {dosud se nic nevymenovalo} for i:=1 to n-1 do if p[i]>p[i+1] then begin vymen(p[i],p[i+1]); b:=true; end until not b; end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 66: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Cvičení: 1. Vygenerujte pole náhodných čísel, připravte si listboxy pro zobrazení setříděného a nestříděného pole a vyzkoušejte si uvedené algoritmy. 2. Protože jsou celá čísla ordinální, dají se velmi rychle setřídit s využitím jejich četnosti – při prvním průchodu polem zjistíme četnost jednotlivých prvků, (k tomu použijeme pole cetnost[i] – kde např. cetnost[3]=4 znamená, že v původním poli jsou čtyři trojky) a potom do pole umístíme postuně každý prvek tolikrát, kolikrát je v poli cetnost. (Druhý průchod) Předpokládáme, že generujeme jednociferná čísla. var cet:array[0..9]of integer;i,j,k:integer; begin for i:=0 to 9 do cet[i]:=0; for i:=1 to n do inc(cet[a[i]]); { listbox2.items.add(inttostr(cet[i])); pomocné zobrazení vypočítaných četností} k:=1; for i:=0 to 9 do for j:=1 to cet[i] do begin a[k]:=i; inc(k); end; for i:=1 to n do listbox2.items.add(inttostr(a[i])); end;

23. Dimenzionání pole – seznámení Složky pole moho být strukturované je-li jejich typem opět pole, původní pole se nazývá dimenzionální. Var M:array[a..b]of array[c..d]of T Užívá se zkrácený zápis array[a..b,c..d]of T, v obou případech jde o stejný typ pole. M[i] – i-tý řádek pole, M[i,j] – prvek v i-tém řádku a j-tém sloupci. Pokud máme definován typ: Type dimpole=array[1..n,1..n]of integer; Var a,b:dimpole; Můžeme použít přiřazovací příkaz a:=b. Pozor, pro pole deklarovaná s anonymním typem Var a: array[1..n,1..n] of integer; B: array[1..n,1..n]of integer; se toto přiřazení použít nedá. Zatím můžeme dvojrozměrné pole zobrazit do Listboxu, příště se seznámíme s komponentou Stringgrid, se kterou vytváříme tabulky s excelovským exteriérem. Dvojrozměrným tabulkám čísel se v matematice říká matice a užívali jsme je například k řešení soustav lineárních rovnic. Poznámka: dají se používat i pole vícerozměrná, ale při velkém počtu indexů se v nich snadno ztrácí orientace. Příklad: a b c d e f g h * #%& můžeme deklarovat jako type dimpole=array[1..3,1..4] of char; var a:dimpole; a[1,2]=b; a[3,1]=*… Příklad Budeme deklarovat obdélníkovou tabulku celých čísel. Naplníme ji ze generátoru náhodnými jednocifernými čísly, zobrazíme a naučíme se ní pracovat na následujících příkladech:

1. Výpis prvního řádku 2. Součet posledního sloupce 3. Nalezení největšího čísla matice a určení počtu těchto maxim.

PDF created with pdfFactory trial version www.pdffactory.com

Page 67: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

const n=10; m=5; type pole=array[1..m,1..n]of integer; var Form1: TForm1; b:pole; … procedure ukaz(a:pole; l:Tlistbox); {zobrazeni tabulky do pole po radcich, ktere si pripravime do retezcu: var i,j:integer; s:string; begin l.clear; for i:=1 to m do begin s:=''; for j:=1 to n do s:=s+inttostr(a[i,j])+' '; l.Items.add(s); end; end; procedure TForm1.Button1Click(Sender: TObject); {naplneni a zobrazeni} var i,j:integer; begin randomize; for i:=1 to m do for j:=1 to n do b[i,j]:=random(10); ukaz(b,listbox1); end; procedure TForm1.Button2Click(Sender: TObject); {1. radek} var i:integer;s:string; begin s:=''; for i:=1 to n do s:=s+inttostr(b[1,i])+' '; showmessage(s); end; procedure TForm1.Button3Click(Sender: TObject); {soucet posledního sloupce} var i,s:integer; begin s:=0; for i:=1 to m do s:=s+b[i,n]; showmessage(inttostr(s)); end; procedure TForm1.Button5Click(Sender: TObject); {maximum a počet jeho vyskytu} var i,j,max,pmax:integer; begin max:=0; pmax:=0; for i:=1 to m do for j:=1 to n do if b[i,j]>max then begin max:=b[i,j]; pmax:=1; end

PDF created with pdfFactory trial version www.pdffactory.com

Page 68: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

else if b[i,j]=max then inc(pmax); showmessage(inttostr(max)+' '+inttostr(pmax)); end;

Cvičení Pracujte dál s tabulkou z předchozího příkladu a naprogramujte řešení následujících problémů:

1. Počet dvojek ve sloupci, jehož číslo zadá uživatel 2. Maximum třetího sloupce 3. Počet sudých čísel v matici

Řešení procedure TForm1.Button6Click(Sender: TObject); var p,i,k:integer; begin k:=spinedit1.value; p:=0; for i:=1 to m do if b[i,k]=2 then inc(p); showmessage(inttostr(p)); end; procedure TForm1.FormCreate(Sender: TObject); begin spinedit1.MinValue:=1; spinedit1.MaxValue:=n; {nastaveni spineditu pro vyber sloupce} end; procedure TForm1.Button4Click(Sender: TObject); var max,i,k:integer; begin max:=-1;; for i:=1 to n do if b[3,i]>max then max:=b[3,i]; showmessage(inttostr(max)); end; procedure TForm1.Button7Click(Sender: TObject); var i,j,p:integer; begin p:=0; for i:=1 to m do for j:=1 to n do if not odd(b[i,j])then inc(p); showmessage(inttostr(p)); end;

24. Procvičování dimenzionálního pole

Vstup dat od uživatele Stejně jako u u jednorozměrného pole můžeme data pro tabulky načítat z komponent Delphi nebo textových či binárních souborů. Ukážeme si vstup z editačního políčka, u textových souborů – pokud by byly ve tvaru tabulek, bychom museli nejprve „rozebrat“ jednotlivé řádky na čísla. const n=4; type

PDF created with pdfFactory trial version www.pdffactory.com

Page 69: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

pole=array[1..n,1..n]of integer; var Form1: TForm1; i,j:integer; {indexy pro zadavani} a:pole; procedure ukaz(a:pole;l:Tlistbox); … procedure TForm1.FormCreate(Sender: TObject); begin i:=1;j:=1; end; procedure TForm1.Button1Click(Sender: TObject); begin if (i<=n) and (j<=n) then begin a[i,j]:=spinedit1.value; if j=n {prechod na dalsi radek} then begin j:=1;inc(i); end else inc(j); {prechod na dalsi prvek} label1.caption:='Zadej prvek a['+ inttostr(i)+','+inttostr(j)+']' end else label1.Caption:='hotovo' ; ukaz(a,listbox1); {prubezne zobrazeni tabulky} end;

Další příklady: (Procvičování práce s dvojrozměrným polem, procedurami a funkcemi) Pracujte s čtvercovou tabulkou náhodně vygenerovaných celých čísel. 1. Definujte funkce pro součet čísel v k-tém sloupci a vypište pod zobrazenou tabulku součty sloupců. 2. Vyhledejte maximum hlavní diagonály. (úhlopříčka z levého horního do pravého dolního rohu tabulky) 3. Vyměňte sloupce, jejichž čísla zadá uživatel. Použijte proceduru na výměnu dvou sloupců a v ní proceduru na výměnu dvou celých čísel. (Deklarujte ji globálně, aby se dala použít i jinde) 4. Setřiďte vzestupně řádek, jehož číslo zadá uživatel. 5. Určete počet nul pod hlavní diagonálou. Řešení 1. function sum(k:integer;a:pole):integer; var s,i:integer; begin s:=0; for i:=1 to m do s:=s+a[i,k]; sum:=s; end; procedure TForm1.Button2Click(Sender: TObject); var i:integer; s:string; begin listbox1.items.add('________________________'); for i:=1 to n do s:=s+' '+inttostr(sum(i,b)); listbox1.items.add(s); end; 2. Není nutné používat dvou vnořených cyklů, stačí si uvědomit, že řádkový a sloupcový index hlavní diagonály jsou stejné. (Podobně pro vedlejší diagonálu jsou indexy [i,n-i+1] procedure TForm1.Button5Click(Sender: TObject);

PDF created with pdfFactory trial version www.pdffactory.com

Page 70: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

var i,max:integer; begin max:=-1; for i:=1 to n do if aa[i,i]>max then max:=aa[i,i]; showmessage(inttostr(max)); end; 3. procedure vymen(var x,y:integer); var p:integer; begin p:=x;x:=y;y:=p; end; procedure vymensloupce(i,j:integer;var b:pole); var k:integer; begin for k:=1 to n do vymen(b[k,i],b[k,j]); end; procedure TForm1.Button3Click(Sender: TObject); var p,q:integer; begin p:=spinedit1.Value; q:=spinedit2.Value; vymensloupce(p,q,aa); ukaz(aa,listbox2); end; 4. procedure tridradek(i:integer;var b:pole); var bu:boolean;k:integer; begin repeAT bu:=false; for k:=1 to n-1 do if b[i,k]>b[i,k+1] then begin vymen(b[i,k],b[i,k+1]); bu:=true; end; until not bu; end; procedure TForm1.Button4Click(Sender: TObject); var p:integer; begin p:=spinedit1.Value; tridradek(P,AA); ukaz(aa,listbox2); end; 5. procedure TForm1.Button2Click(Sender: TObject); var i,j,p:integer; begin p:=0; for i:=1 to n do for j:=1 to i-1 do if aa[i,j]=0 then inc(P); showmessage(inttostr(p)); end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 71: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

25. Komponenta StringGrid a zobrazení tabulek Kdybychom chtěli pracovat s dvojrozměrným polem řetězců nebo čísel s různými počty cifer, museli bychom si připravit složitější zobrazovací procedury. Delphi mají komponentu StringGrid na paletě Additional, tabulku, která slouží k zobrazení řetězců a je navržena podle spreadsheetů v tabulkových kalkulátorech. Kromě buněk pro zobrazení disponuje dalšími vlastnostmi a funkcemi, z nichž s některými se seznámíme. Vlastnosti: ColCount, RowCount – počet sloupců, řádků (číslováno od nuly) Cells[Col, Row]:string obsah buňky ve sloupci col a řádku row. Př. Stringgrid1.cells[2,2]:='blabla’; Fixed…0. řádek a sloupec – obvykle barevně odlišný (Fixcolor) Procházení tabulkou: For i:=0 to stringgrid1.colcount-1 do For j:=0 to stringgrid1.rowcount-1 do… Zobrazení dvourozměrného pole tabulkou procedure ukaz(a:tabulka); var i,j:integer; begin for i:=1 to n do for j:= 1 to n do form1.stringgrid1.cells[j,i]:=inttostr(a[i,j]) end; (u dvourozměrného pole je první index řádkový, zatímco u StrngGridu sloupcový) Událost OnSelectCell: (klapnutí myši do tabulky) procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin edit1.Text:=stringgrid1.Cells[Acol,ARow]; end; zkopíruje aktuální buňku do editačního okna. Jednotlivé sloupce nebo řádky jsou typu TStrings – jako např. items listboxu. Stringgrid1.cols[1]:=listbox1.items; zkopíruje obsah listboxu do 1. sloupce tabulky. Více – nápověda Delphi. Příklad Připravte si do dvou listboxů slovníček – do každého slovíčka v jednom jazyce, ekvivalenty v těchže řádcích. Přeneste je do dvou sloupců stringgridu a potom klepne-li uživatel do buňky, zobrazí se slovíčko ve druhém jazyce. procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin for i:=1 to listbox1.Items.Count do stringgrid1.Cells[0,i]:=inttostr(i); stringgrid1.RowCount:=listbox1.Items.Count ; stringgrid1.colcount:=3; stringgrid1.Cols[1]:=listbox1.items; stringgrid1.cols[2]:= listbox2.items; {1.radek v listboxech nechame prazdny, prepise se titulkem} stringgrid1.Cells[1,0]:='èesky'; stringgrid1.cells[2,0]:='anglicky'; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin if acol=1 then showmessage(stringgrid1.Cells[2,arow]) else

PDF created with pdfFactory trial version www.pdffactory.com

Page 72: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

if acol=2 then showmessage(stringgrid1.Cells[1,arow]) end; Poznámky: Options: GoEditing na true – jde přímo editovat Výběr oblasti: procedure TForm1.Button1Click(Sender: TObject); var myRect: TGridRect; begin myRect.Left := 1; myRect.Top := 1; myRect.Right := 10; myRect.Bottom := 10; StringGrid1.Selection := myRect; end; Analogicky lze získat souřadnice obdélníkové pravoúhlé oblasti: procedure TForm1.Button3Click(Sender: TObject); var a,,c,d:integer; myRect: TGridRect; begin Myrect:=StringGrid1.Selection; a:=myRect.Left; b:=myRect.Top; c:=myRect.Right; d:=myRect.Bottom; end

Cvičení Vygenerujte čtvercovou tabulku náhodných celých čísel. Připravte si dva StringGridy, do jednoho zobrazte původní tabulku a do druhého modifikace:

1. Setřiďte vedlejší diagonálu vzestupně 2. Zobrazte jednotkovou matici – tj. matici, která má na hlavní diagonále samé jedničky a jinak nuly 3. Vytvořte matici transponovanou (vyměňte sloupce a řádky) 4. Vyměňte hlavní a vedlejší diagonálu 5. Zobrazte Strinnggrid, který bude vypadat, jako tabulka v Excelu – sloupce označené písmeny, řádky

čísly.

Řešení 1. procedure TForm1.Button4Click(Sender: TObject); var i:integer; bu:boolean; begin repeat bu:=false; for i:=1 to n-1 do if b[i,n-i+1]>b[i+1,n-i] then begin bu:=true; vym( b[i,n-i+1],b[i+1,n-i]) end until not bu; viz(b,stringgrid1); end; 2. procedure TForm1.Button3Click(Sender: TObject); var i,j:integer; begin for i:=1 to n do for j:=1 to n do if i=j then jed[i,j]:=1 else jed[i,j]:=0; end;

PDF created with pdfFactory trial version www.pdffactory.com

Page 73: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

4. procedure TForm1.BitBtn2Click(Sender: TObject); var i:integer; begin for i:=1 to n do vymen(a[i,i],a[i,n-i+1]); end; 3. procedure TForm1.Button1Click(Sender: TObject); {vymenime cisla osove soumerna podle hlavni diagonaly} var i,j:integer; begin for i:=1 to n do for j:=1 to i-1 do vymen(a[i,j],a[j,i]); end; 5. procedure TForm1.Button3Click(Sender: TObject); var a:char;i:integer; begin a:='A'; for i:=1 to n do begin stringgrid1.cells[i,0]:=a; inc(a); end; a:='1'; for i:=1 to n do begin stringgrid1.cells[0,i]:=a; inc(a); end; end;

26. Statické pole v procedurách a funkcích, opakování Shrňme si klady a zápory statických polí: Výhody: § Možnost uložit více hodnot stejného typu v jedné proměnné § Snadná manipulace s daty prostřednictvím indexů § Možnost volit rozsah indexů, indexovat i jinými typy než celočíselnými Nevýhody: § Velikost pole nelze měnit za běhu programu, takže se musí na začátku nadeklarovat maximální potřebná

velikost § Protože velikost pole musí být známa v době překladu, nedá se ani měnit, ani nastavit, což by omezovalo

použití polí jako parametrů podprogramů. (Velká nevýhoda původního Pascalu) Řešením posledního problému v Delphi je možnost pracovat s otevřeným polem.

Práce s otevřeným polem V deklaraci formálních parametrů se uvede pouze typ pole, jehož velikost se doplní podle velikosti skutečného parametru. Skutečnou velikost pole v proceduře pak zjistíme pomocí standardních funkcí Low High, Protože Low vrací vždycky nulu a high počet prvků v poli, je třeba indexy vhodně posouvat a nejraději indexovat od nuly. Příklad Nadeklarujeme dvě celočíselná pole různé délky, naplníme je a zobrazíme v listboxu toutéž procedurou. const n=20; type cisla1=array[0..n]of integer; cisla2=array[0..2*n]of integer; {pole n+1=10 celych cisel} var

PDF created with pdfFactory trial version www.pdffactory.com

Page 74: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Form1: TForm1; a:cisla1; b:cisla2; procedure ukaz(a:array of integer;l:Tlistbox); var i:integer; begin l.clear; for i:=0 to high(a) do l.items.add(inttostr(a[i])); end; procedure TForm1.Button1Click(Sender: TObject); var i:integer; begin for i:=0 to n do a[i]:=i; for i:=0 to 2*n do b[i]:=i; ukaz(a,listbox1); ukaz(b,listbox2); end;

Násobení matic Matice lze sčítat, násobit reálným číslem (c[i,j]:=a[I,j]+b[I,j], c[I,j]:=k[a[i,j]), ale také násobit vzájemně.

∑=

=n

kji jkbkiac

1, ],[*],[

Příklad:

=

18482

3120

*4321

matice=array[1..n,1..n]of integer; … procedure nasob(a,b:matice;var c:matice); var i,j,k,p:integer; begin for i:=1 to n do for j:=1 to n do begin p:=0; for k:=1 to n do p:=p+a[i,k]*b[k,j]; c[i,j]:=p; end; end; Při násobení matice jednotkovou maticí, dostaneme původní matici. (Vyzkoušejte)

Cvičení Pracujte s čtvercovou tabulkou náhodně vygenerovaných celých čísel a dvěma StringGridy, jedním pro zobrazení původní tabulky, druhým pro zobrazení úprav. 1. Setřiďte matici tak, že bude platit: a[1,1]<=a[1,2]<=..a[2,1]<=a[2,2]…<=a[n.n]. 2. Setřiďte matici tak, že povyměňujete řádky, aby se jejich obsah nezměnil a první sloupec byl setříděn vzestupně.

Řešení 1. procedure TForm1.Button3Click(Sender: TObject); {matici nejprve prerovname do jednorozmerneho pole, to setridime a prevedeme napzatek} var c:array[1..n*n]of integer;i,j,k,p:integer; bu:boolean; begin k:=1;

PDF created with pdfFactory trial version www.pdffactory.com

Page 75: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

for i:=1 to n do for j:=1 to n do begin c[k]:=b[i,j]; inc(k); end; repeat bu:=false; for i:=1 to n*n-1 do if c[i]>c[i+1] then begin p:=c[i]; c[i]:=c[i+1]; c[i+1]:=p; bu:=true; end; until not bu; k:=1; for i:=1 to n do for j:=1 to n do begin b[i,j]:=c[k]; inc(k); end; ukaz(b,stringgrid2); end; 2. procedure vymen(var x,y:integer); var p:integer; begin p:=x;x:=y;y:=p;end; procedure radky(x,y:integer;var b:pole); var i:integer; begin for i:=1 to n do vymen(b[x,i],b[y,i]); end; procedure TForm1.Button2Click(Sender: TObject); var j:integer;bu:boolean; begin repeat bu:=false; for j:=1 to n-1 do if a[j,1]>a [j+1,1] then begin radky(j,j+1,a); bu:=true; end until not bu; end;

27. Dynamické pole V klasickém Pascalu je pole je statická struktura, jeho velikost musí být známa již v době překladu. (deklarace) V C++, Delphi od verze 4 existuje dynamické pole, které nemá pevně stanovenou délku. Deklarace: type Dynpole=array of Zakladnityp; var a: Dynpole… Před prvním použitím je nutné nastavit jeho velikost a alokovat tak volný blok paměti. SetLength(a,10) … v paměti se vyhradí prostor pro 10 hodnot základního typu. Pak s ním lze pracovat běžným způsobem (a[3]:=4…) Indexy dynamických polí začínají vždy od nuly. Zde: 0..9. Nejvyšší index – High(a) Nejnižší index – Low(a) – vrací vždy 0. Změna velikosti pole za běhu programu:

PDF created with pdfFactory trial version www.pdffactory.com

Page 76: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

Zvětšení rozsahu: SetLength Zmenšení: a:=copy(a,0,5) – v poli A zůstane 5 prvků od pozice 0. Celé pole se zruší: a:=nil; V paměti vyhrazené programu je ve skutečnosti jen ukazatel (adresa) jiné části paměti, které se říká halda a na kterou se ukládají objekty dynamicky alokované za běhu programu. Nil je ukazatel nikam. Pokud dojde k překročení rozsahu indexů, nevzniká chyba, ale programátor by měl všechny podobné problémy správně ošetřit. Velikost objektu v Bytech obecně určuje funkce SizeOf(object), u dynamického pole ale vždy vrací 4B – velikost ukazatele.

Přiřazování polí Statické: obsah se zkopíruje, takže v paměti existují dvě stejná pole Dynamické – do nové proměnné se přiřadí pouze ukazatel na existující pole. Změníme-li něco v novém poli, změní se to i v původním. Proto například není možné vyměnit dva objekty typu Tstrings (např. items listboxu) přes třetí, ale pouze pomocí pomocného statického pole.

Příklady: 1. Zadejte řadu příjmení postupným přidáváním do listboxu, načtěte je do dynamického pole a upravte tak, že, pokud je poslední písmeno – á, připojíte před řetězec slovo paní, jinak slovo pán. Vyhledejte nejdelší jméno. type pole=array of string; var Form1: TForm1; a:jmena; implementation {$R *.DFM} procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); {pridani polozky do listboxu} begin if key=#13 then begin listbox1.items.add(edit1.text); Edit1.clear; edit1.setfocus; end; end; procedure TForm1.Button1Click(Sender: TObject); var i,n:integer;p:char;max:string; begin n:=listbox1.items.count; setlength(a,n); max:=''; for i:=0 to high(a) do begin a[i]:=listbox1.items[i]; if length(a[i])>length(max) then max:=a[i]; end; showmessage(max); end; procedure TForm1.Button2Click(Sender: TObject); var i:integer; x:string; begin for i:=0 to high(a) do begin x:=a[i]; if x[length(x)]='á' {poslední písmenko slova – s řetězcem lze pracovat jako s polem znakú} then a[i]:='paní '+a[i] else a[i]:='pan '+a[i];

PDF created with pdfFactory trial version www.pdffactory.com

Page 77: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

end; listbox1.clear; for i:=0 to high(a) do listbox1.items.add(a[i]); end; 2. Vygenerujte řadu náhodných čísel do dynamického pole a zobrazte je do Listboxu. Nechte pak zadat uživatele číslo a pole přerovnejte tak, aby na jeho začátku byla čísla menší než zadané číslo, za nimi pak čísla větší než zadané číslo. Indexem i procházíme pole zleva, indexem j zprava. Když narazíme na prvky, které do svých částí pole nepatří, vyměníme je. Postup opakujeme tak dlouho, dokud nezkřížíme indexy i a j. procedure TForm1.Button1Click(Sender: TObject); {nastavi delku pole podle požadavku uživatele} begin setlength(a,spinedit1.Value); end; procedure ukaz(b:pole;l:Tlistbox); {zobrazi pole do listboxu} var i:integer; begin l.Clear; for i:=0 to high(b) do l.Items.add(IntToStr(b[i])); end; procedure TForm1.BitBtn1Click(Sender: TObject); {vygeneruje pole a zobrazi ho} vAR i:integer; begin listbox1.Clear; for i:=0 to high(a) do a[i]:=random(20); ukaz(a,listbox1); end; procedure TForm1.BitBtn2Click(Sender: TObject); {prerovnani} var x,i,j:integer; begin x:=spinedit1.Value; i:=0; j:=high(a); repeat while a[i]<x do inc(i); while a[j]>x do dec(j); if i<=j then begin vymen(a[i],a[j]); inc(i); dec(j); end; until i>j; ukaz(a,listbox2); end;

Dvojrozměrné dynamické pole type TMessageGrid = array of array of string; var a: TMessageGrid; Pokud pracujeme s obdélníkovým polem můžeme ho zpracovávat obvyklým způsobem: setlength(a,10,20); Je možné také vytvářet pole, jejich řádky mají různý počet prvků.

PDF created with pdfFactory trial version www.pdffactory.com

Page 78: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

var Ints: array of array of Integer; SetLength(Ints,10); SetLength(Ints[2], 5); – druhý řádek bude mít pět prvků. Příklad: Vytvoření trojúhelníkové matice řetězců var A : array of array of string; I, J : Integer; begin SetLength(A, 10); for I := 0 to High(A) do begin SetLength(A[I], I); for J := 0 to High(A[I]) do A[I,J] := IntToStr(I) + ',' + IntToStr(J) + ' '; end; end;

Cvičení 1. Vygenerujte dynamické pole náhodných čísel do listboxu, seřaďte jeho prvky tak, že nejprve budou čísla lichá, potom čísla sudá, na pořadí nezáleží.. (Pokuste se obejít bez pomocného pole) 2. Napište program pro výpis všech prvočísel menších než dané číslo. (Zadá uživatel). Použijte algoritmus Eratosthenova síta: Začneme dvojkou a vyškrtáme z pole všechny násobky dvou. (kromě dvojky). Pak pokračujeme dál – ponecháme trojku a vyškrtáme všechny násobky trojky…až v poli zůstanou pouze prvočísla. Řešení 1. procedure TForm1.BitBtn3Click(Sender: TObject); var i,l,s:integer; {liche zleva, sude zprava} begin l:=1;s:=high(a); for i:=1 to high(a) do if odd(a[i]) then begin a[l]:=a[i]; inc(l); end else begin a[s]:=a[i]; dec(s); end; ukaz(a,listbox3); end; 2. procedure TForm1.prvoci2Click(Sender: TObject); var a:array of boolean; n:integer; d,p,i:integer; begin n:=strtoint(edit1.Text); setlength(a,n+1); for i:=2 to n do a[i]:=true; {a[5]=true znamena, ze se 5 v poli nachazi. Nejprve tam tedy umistime vsechna cisla mensi nez dane} for i:=2 to n do begin d:=2*i; while d<=n do begin a[d]:=false;; d:=d+i; {vyskrtavani nasobku i} end; end; memo1.Lines.clear; for i:=2 to n do

PDF created with pdfFactory trial version www.pdffactory.com

Page 79: 1. Úvod, Algoritmus a jeho charakteristiky · • funkcionální jako Prolog nebo Lisp ... PDF created with pdfFactory trial version ... 6, 1,5 (x+y=45, x-y=33, 2x =12) Bílé a

if a[i] then listbox11.items.add(inttostr(i)); end;

Obsah 1. Úvod, Algoritmus a jeho charakteristiky........................................................................................................ 1 2. Dephi – úvod do prostředí, Object Pascal – úvod do syntaxe.......................................................................... 4 3. Proměnná a její deklarace, přiřazovací příkaz ................................................................................................ 9 4. Složený příkaz, deklarace konstanty ............................................................................................................ 12 5. Podmíněné příkazy – if ............................................................................................................................... 15 6. Podmíněné příkazy – pokračování............................................................................................................... 17 7. Cykly – příkaz while................................................................................................................................... 21 8. Cykly – příkaz repeat .................................................................................................................................. 23 9. Skalární (jednoduché) typy dat .................................................................................................................... 27 10. Cyklus FOR.............................................................................................................................................. 30 11. Typ interval a větvení case ........................................................................................................................ 32 12. Správnost a efektivnost algoritmu.............................................................................................................. 35 13. Vnořené cykly .......................................................................................................................................... 38 14. Procedury – první seznámení..................................................................................................................... 40 15. Procedury po druhé................................................................................................................................... 43 16. Funkce...................................................................................................................................................... 46 17. Programové jednotky ................................................................................................................................ 50 18. Opakování ................................................................................................................................................ 53 19. Datový typ pole ........................................................................................................................................ 57 20. Pole – vstup dat od uživatele, další příklady............................................................................................... 59 21. Vyhledávání v poli.................................................................................................................................... 62 22. Třídění...................................................................................................................................................... 64 23. Dimenzionání pole – seznámení ................................................................................................................ 66 24. Procvičování dimenzionálního pole ........................................................................................................... 68 25. Komponenta StringGrid a zobrazení tabulek.............................................................................................. 71 26. Statické pole v procedurách a funkcích, opakování .................................................................................... 73 27. Dynamické pole........................................................................................................................................ 75 Obsah............................................................................................................................................................. 79

PDF created with pdfFactory trial version www.pdffactory.com


Recommended