Zadání druhého zápočtového projektu Základy algoritmizace, 2005 Jiří Dvorský 2 května 2006 Obecné pokyny Celkem je k dispozici 8 zadání příkladů Každý student obdrží jedno zadání Vzhledem k tomu, že odpadly pondělní cvičení, majáles atd a tudíž část z Vás by mohla vybrané zadaní nahlásit cvičícímu až dost pozdě, rozhodl jsem se, že příklady Vám budou přiděleny Z čísla Vašeho loginu vezmete koncové trojčíslí resp dvojčíslí, z něho spočítáte zbytek po dělení 8 Tím dostanete číslo v rozmezí 0 až 7 K němu pak přičtete 1 a dostáváte číslo příkladu Pro Vaší informaci, tato jednoduchá metoda rozděluje příklady mezi Vás zhruba stejně dobře jako složitá hašovací funkce Příklad: já mám login dvo26, takže 26 modulo 8 je 2 plus 1 je 3 Takže bych měl příklad číslo 3 Příklady proberu na přednášce 9 a 10 května Na mém webu jsou k dispozici ke každému příkladu testovací vstupy Na těchto vstupech bude příslušný cvičící Vaše programy testovat Abyste měli kontrolu, zda Váš program funguje správně, jsou zde i výstupy z mých kontrolních programů Tudíž si můžete sami výsledek Vašeho programu porovnat (u příkladu 8 se může stát, že se Vaše výstupy budou díky zaokrouhlovacím chybám lišit na posledních desetinných místech, neměly by se však lišit zásadně třeba o desetiny) Z předchozího bodu plyne, že jsem všechny příklady naprogramoval Z toho dále plynou, že: 1 doba běhu žádného z osmi programů nepřekročila cca minutu, dvě (Pentium 4, 24 GHz), 2 napsání žádného programu mi netrvalo více než hodinku s rezervou na kafe Tudíž Vám by to nemělo zabrat déle než odpoledne či dvě Nejsou to žádné nevyřešitelné příklady 1
1 příklad Sjednocení dvou množin Jsou dány dvě množiny A = {a 1,a 2,,a n } a B = {b 1,b 2,,b m },kdea i,b i,n,m N Napište program, který sestrojí sjednocení C = A B Jestliže A = {2, 3, 5} a B = {1, 3, 4, 5} pak C = A B = {1, 2, 3, 4, 5} 2 příklad Průnik dvou množin Jsou dány dvě množiny A = {a 1,a 2,,a n } a B = {b 1,b 2,,b m },kdea i,b i,n,m N Napište program, který sestrojí průnik C = A B Jestliže A = {2, 3, 5} a B = {1, 3, 4, 5} pak C = A B = {3, 5} 3 příklad Rozdíl dvou množin Jsou dány dvě množiny A = {a 1,a 2,,a n } a B = {b 1,b 2,,b m },kdea i,b i,n,m N Napište program, který sestrojí rozdíl C = A B Jestliže A = {2, 3, 5} a B = {1, 3, 4, 5} pak C = A B = {2} k příkladům 1 až 3 Vstupem do programu budou dva textové soubory, které budou obsahovat sekvence čísel, na každém řádku jedno číslo Čísla budou v rozsahu 0 x<10 8, čísla se mohou (a určitě budou) opakovat Počet čísel bude v obou souborech shodný 10 6 Jak už to v životě bývá, data přicházející od uživatelů většinou nebývají ve formě, kterou bychom mohli ihned zpracovat Množiny se kterými se bude pracovat je nutné nejprve z daných sekvencí vytvořit - odstranit duplicity Výstupem z programu bude textový soubor, na každém řádku bude jedno číslo z Vaší výsledné množiny Čísla budou seřazena vzestupně Jména vstupních souborů a výstupního souboru se budou zadávat jako argumenty z příkazové řádky ve tvaru: VasProgram Vstup1 Vstup2 Vystup Vzhledem k rozsahu množin není možné využít naivní algoritmus, spočívající v porovnání každého prvku s každým Složitost tohoto algoritmu je O(n 2 ), což pro n =10 6 činí 10 12! Výsledku byste se taky nemuseli dočkat 2
4 d 2 6 b f 1 3 5 a c e (a) Strom T 1 (b) Strom T 2 4 2 6 β 1 3 7 α γ (c) Strom T 3 (d) Strom T 4 Obrázek 1: Ukázky stromů Klíčem k úspěchu je využití některého ze třídících algoritmů nebo datových struktur, možností řešení je relativně mnoho Při některých způsobech řešení není dokonce nutné vytvářet množinu (odstraňování duplicit atd) dopředu, je možné zpracovávat přímo sekvenci čísel ze vstupních souborů 4 příklad Struktura stromů Na vstupu jsou dány dva binární vyhledávací stromy A a B Napište program, který rozhodne, zda dané dva stromy mají shodnou strukturu Struktura stromu je nezávislá na datech ve stromu uložených, jde pouze o existenci či neexistenci uzlů a hran mezi nimi Uvažujme stromy na obrázku 1 Shodnou strukturu se stromem T 1 má strom T 2, přestože obsahují různá data Strom T 1 astromt 3 nemají shodnou strukturu z uzlu označeném číslem 6 vede v jednom případě hrana doleva v druhém případě vede doprava (lhostejno, že jeden uzel obsahuje číslo 5 a druhý 7) Pochopitelně, každý strom má shodnou strukturu sám se sebou Předpokládejte, že oba stromy nebudou prázdné Stromy budou obsahovat pouze celá čísla (typ int) Stromy budou zadány ve formě textového souboru jako posloupnost čísel, na každém řádku bude pouze jedno číslo Stromy ze souborů získáte tak, že čísla načítaná postupně z textového souboru budete vkládat, pomocí obvyklého algoritmu, do binárního vyhledávacího stromu (jednoduchá, nevyvážená varianta) 3
Jména dvou vstupních souborů se stromy budou zadána jako parametr příkazové řádky ve tvaru: VasProgram Vstup1 Vstup2 Výsledek vypíše Váš program na konzolu ve tvaru Stromy maji/nemaji shodnou strukturu, žádná jiná informace se nepožaduje V tomto příkladě máte opět několik možností řešení Jednak můžete vhodným způsobem systematicky projít oba dva stromy, výsledky průchodů si uložit nejlépe lineárním způsobem a tuto lineární formu obou stromů pak navzájem porovnat Druhou možností je systematicky procházet oba stromy najednou a porovnávat je on-line Uvědomte si, že data uložená v uzlech Vás vlastně ani nemusí zajímat Data načítaná ze vstupních souborů slouží jen k tomu, aby se dal binární strom nějakým (opakovatelným) způsobem poskládat 5 příklad Podstromy Na vstupu jsou dány dva binární vyhledávací stromy A a B Napište program, který rozhodne, kolikrát se daný strom B vyskytuje ve stromu A jako podstrom Stejně jako v předchozím příkladu je struktura stromu je nezávislá na datech ve stromu uložených, jde pouze o existenci či neexistenci uzlů a hran mezi nimi Uvažujme stromy na obrázku 1 Předpokládejme, že jako podstrom budeme uvažovat strom T 4 Ve stromu T 1 se jako podstrom vyskytuje pouze jednou: α 1, β 2, γ 3 Protože strom T 2 má shodnou strukturu jako strom T 1 je počet výskytů stejný: α b, β d, γ f Pochopitelně, každý strom je sám sobě podstromem s počtem výskytu 1 V obou stromech jsou možné další dva výskyty podstromu: α 2, β 4, γ 6 α a, β b, γ c V tomto případě si ale neodpovídají hrany u uzlů α, γ a2,6respb, f Uuzlů α a γ hrany vedoucí dál neexistují, u uzlů 2, 6 resp b, f existují hrany vedoucí dále Proto tento výskyt neuvažujte uvažujte jen výskyty přesně odpovídající danému podstromu Předpokládejte, že oba stromy nebudou prázdné Stromy budou obsahovat pouze celá čísla (typ int) Stromy budou zadány ve formě textového souboru jako posloupnost čísel, na každém řádku bude pouze jedno číslo 4
n-gram četnost a 5 b 2 c 1 d 1 r 2 Tabulka 1: Výsledné 1-gramy Stromy ze souborů získáte tak, že čísla načítaná postupně z textového souboru budete vkládat, pomocí obvyklého algoritmu, do binárního vyhledávacího stromu (jednoduchá, nevyvážená varianta) Jména dvou vstupních souborů se stromy budou zadána jako parametr příkazové řádky ve tvaru: VasProgram SouborSeStromem SouborSPodstromem Výsledek vypíše Váš program na konzolu ve tvaru Pocet vyskytu podstromu: nnnnn, žádná jiná informace se nepožaduje V tomto příkladě je asi nejlepším řešením nějakým vhodným způsobem systematicky projít oba dva stromy, výsledky průchodů si uložit nejlépe lineárním způsobem a potom určit kolikrát se lineární forma podstromu vyskytuje ve velkém stromu Uvědomte si, že data uložená v uzlech Vás vlastně ani nemusí zajímat Data načítaná ze vstupních souborů slouží jen k tomu, aby se dal binární strom nějakým (opakovatelným) způsobem poskládat 6 příklad Četnost n-gramů Na vstupu je dán řetězec délky m, A = a 1 a 2 a m Sestavte tabulku četnosti všech n-gramů obsažených v řetězci A n-gram je definován jako řetězec B = b 1 b 2 b n délky n, který je podřetězcem řetězce A Výslednou tabulku n-gramů setřiďte podle abecedy a spolu s jejich četnostmi vypište do textového souboru ve tvaru: n-gram četnost n-gram četnost n-gram četnost Mějme řetězec A = abracadabra Výsledekpron = 1 je uveden v tabulce 1, pro n = 2 v tabulce 2 a pro n = 3 pak v tabulce 3 Řetězec A bude uložen ve vstupním textovém souboru 5
n-gram četnost ab 2 ac 1 ad 1 br 2 ca 1 da 1 ra 2 Tabulka 2: Výsledné 2-gramy n-gram četnost abr 2 aca 1 ada 1 bra 2 cad 1 dab 1 rac 1 Tabulka 3: Výsledné 3-gramy Vstupní text je v angličtině, psán pouze malými písmeny, znaky s diakritikou se nebudou vyskytovat V textu se mimo písmen mohou vyskytovat pouze mezery Mezera se bere do úvahy při vytváření n-gramů z daného textu Parametr n předpokládejte v intervalu 1 n 100 Jméno vstupního souboru, parametru n, jméno výstupního souboru bude zadáno jako parametr příkazové řádky ve tvaru: VasProgram Vstup n Vystup Pro úspěšné vyřešení tohoto příkladu je nutné navrhnout datovou strukturu, jednak pro rychlé vkládání nových n-gramů a jednak pro rychlé vyhledávání již nalezených n-gramů (těm se pouze inkrementuje četnost výskytu) Uvědomte si, že n-gramy nemusí být v průběhu zpracování textu ve Vaší datové struktuře nezbytně nutně setříděny Abecední setřídění všech nalezených n-gramů lze provést až nakonec Lze ovšem navrhnout datovou strukturu, která bude n-gram rovnou i třídit 7 příklad Četnost slovních kontextů Je dán textový soubor Spočtěte četnost všech dvojic sousedních slov tj dvojic slov, které spolu v textu bezprostředně sousedí Výsledný seznam dvojic slov setřiďte sestupně (od největšího k nejmenšímu) podle četnosti výskytu dvojic slov a vypište do textového souboru ve tvaru: 6
Dvojice slov Četnost mouse mouse 2 mouse monitor 2 computer mouse 2 monitor computer 1 Tabulka 4: Tabulka četností dvojic slov první slovo dvojice druhé slovo dvojice četnost první slovo dvojice druhé slovo dvojice četnost první slovo dvojice druhé slovo dvojice četnost Je dán tento vstupní text: computer mouse monitor computer, mouse; mouse mouse monitor V textu se tedy vyskytují slova: monitor, mouse a computer Dvojiceslov jsou tyto: computer mouse, mouse monitor, monitor computer, computer mouse, mouse mouse, mouse mouse, mouse monitor Výsledkem je tabulka 4 Vstupní text je v angličtině, psán pouze malými písmeny, znaky s diakritikou se nebudou vyskytovat Slovo je definováno jako souvislá posloupnost znaků z množiny {a,,z} Za dvojice sousedních slov se považují i ty dvojice, které jsou odděleny konci řádků, interpunkčními znaménky atd Položky seznamu jsou setříděny nejprve podle četnosti Položky které mají stejnou četnost se třídí dále podle prvního slova ve dvojici a pokud je i první slovo stejné, třídí se nakonec podle druhého slova Ve všech případech se třídí sestupně Jméno vstupního textového souboru, jméno výstupního souboru bude zadáno jako parametr příkazové řádky ve tvaru: VasProgram Vstup Vystup Pro úspěšné vyřešení tohoto příkladu je nutné navrhnout datovou strukturu, jednak pro rychlé vkládání nových dvojic slov a jednak pro rychlé vyhledávání již nalezených dvojic slov (těm se pouze inkrementuje četnost výskytu) Setřídění podle četnosti výskytu je možné provést až nakonec, kdy už jsou známy konečné hodnoty jednotlivých četností 7
Slovo Četnost Pravděpodobnost Entropie [bity] computer 3 3/9 1,584962501 mouse 4 4/9 1,169925001 monitor 2 2/9 2,169925001 Tabulka 5: Výpočet entropie mouse 1,169925001 computer 1,584962501 monitor 2,169925001 Tabulka 6: Výsledek výpočtu entropie 8 příklad Entropie slov v textu Je dán textový soubor Vypočtěte entropii všech různých slov, které se v textu vyskytují Výsledný seznam slov setřiďte vzestupně podle entropie a vypište do textového souboru ve tvaru: slovo entropie slovo entropie slovo entropie Entropie H(A) jevua, který nastane s pravděpodobností p A je definována jako: H(A) = log 2 p A Jednotkou entropie je jeden bit V našem případě jsou za jevy považována všechna různá slova v textu Pravděpodobnost určíme jako podíl četnosti daného slova ku celkové četnosti všech slov Je dán tento vstupní text: computer mouse monitor computer, mouse; mouse mouse monitor computer V textu se vyskytují tato unikátní slova: monitor, mouse a computer Celková četnost všech slov je 9 Jednotlivé kroky výpočtu jsou uvedeny v tabulce 5 Výsledný seznam slov je uveden v tabulce 6 Vstupní text je v angličtině, znaky s diakritikou se nebudou vyskytovat Slovo je definováno jako souvislá posloupnost znaků z množiny {a,,z} Jméno vstupního textového souboru, jméno výstupního souboru bude zadáno jako parametr příkazové řádky ve tvaru: VasProgram Vstup Vystup 8
Pro úspěšné vyřešení tohoto příkladu je nutné navrhnout datovou strukturu, jednak pro rychlé vkládání nových slov a jednak pro rychlé vyhledávání již nalezených slov (těm se pouze inkrementuje četnost výskytu) Výpočet entropie a setřídění výsledků podle této veličiny je možné provést až nakonec, kdy už jsou známy konečné hodnoty jednotlivých četností 9