Jak na pro­jek­ty v ja­zy­ce C

© Damig, 2004 – 2016
Koncept

Úlohy k procvičení

Úvod

Na této stránce najdete sbírku třicetiminutovek, tedy programátorských úloh, které byste měli zvládnout naprogramovat do 30 minut. Pokud vám některá úloha bude trvat déle, nevadí. Trénujte a časem to půjde rychleji.

Vždy několik takových kratších úloh tvoří větší celek. Pokud je budete řešit v pořadí, v jakém jsou zadány, můžete využít výsledky předchozích k řešení dalších úloh.

Úlohy slouží k procvičení základních programátorských obratů. Tyto obraty byste měli umět používat bez zdlouhavého přemýšlení. Chcete-li řešit projekty, které vás opravdu zajímají, trénujte. Bez zdlouhavého přemýšlení o trivialitách bude programování zábavou a ne důvodem k bolení hlavy.

Každou úlohu řešte vytvořením podprogramů a nepoužívejte globální proměnné. I když to zpočátku nemusí tak vypadata, opravdu to šetří a zjednodušuje práci. Zvláště když pracujete na něčem větším a zajímavějším.

Úlohy

Kalendář

Den v týdnu

Napište funkci, která ze zadaného data ve formátu den, měsíc vypočítá, jaký den v týdnu na toto datum připadá v roce 2015. Napište program, který tuto funkci otestuje. Nepoužívejte knihovní funkce, které tento problém mohou řešit. Vymyslete řešení sami.

Tip 1: Vracejte konstantu vytvořenou v typu enum nebo číslo od 0 do 6, kde 0 je pondělí a 6 je neděle. Pro tisk výsledku pak můžete použít pole textových řetězců s názvy dnů v týdnu.

Tip 2: Nepoužívejte switch ani zřetězené příkazy if. Použijte místo toho konstantní pole s počty dnů pro jednotlivé měsíce.

Co asi bude potřeba: funkce, cyklus, pole, výčtový typ enum.


Přestupný rok

Napište funkci, která bude vracet logickou hodnotu true, když zadaný rok je přestupným rokem a false, když přestupným rokem není. S roky od počátku kalendáře, tedy od roku 1, zacházejte podle gregoriánského kalendáře (i když ten platí až od roku 1582).

Rok je podle gregoriánského kalendáře přestupný tehdy, když je dělitelný 4, přičemž roky dělitelné 100 jsou přestupné jen tehdy, když jsou dělitelné zároveň 400.

Tip: Zkuste celou funkci vymyslet co nejkratší, tedy bez použití podmíněného příkazu, pouze jako logický výraz.


Obecný den v týdnu

Upravte funkci pro výpočet dne v týdnu ze zadaného data tak, aby akceptovala datum včetně roku. Uvažujte přitom i přestupné roky. Otestujte upravenou funkci pomocí programu. (Poznámka: Víte který den v týdnu jste se narodili?)

Tip: Využijte funkci pro testování přestupných let.


Celé týdny v měsíci

Vytvořte funkci, která vrátí počet celých týdnů v zadaném měsíci a roku. Celý týden je takový týden, který začíná i končí ve stejném měsíci.


Pracovní dny

Napište funkci, která vrátí počet pracovních dní zadaného měsíce a roku. Svátky a jiná mimořádná volna neberte v úvahu. Použijte dříve vytvořené funkce.

Tip: Vyhněte se použití cyklu pro průchod všemi dny zadaného měsíce.


Víkendové dny

Vytvořte funkci, která vrátí počet víkendových dní zadaného měsíce a roku.

Generátor náhodných polí

Vyrobte funkce pro generování náhodného obsahu pole zadané velikosti pro testování řadících algoritmů. Funkce budou mít tři parametry: pole celých čísel, délku a počet možných duplicitních klíčů pro každou hodnotu. Pokud bude počet duplicitních klíčů zadán například 5, potom může mít každý vygenerovaný klíč 0 až 5 kopií (použijte funkce rand a srand ze stdlib.h).

Funkce musí být schopny inicializovat i velmi dlouhá pole s miliony prvků. Tato dlouhá pole vyrábějte dynamickou alokací, protože na zásobník by se nemusela vejít.

Tip: Inicializujete-li generátor náhodných čísel (funkce srand) vždy stejnou hodnotou, bude funkce rand dávat vždy stejnou posloupnost náhodných čísel.

Neklesající posloupnost

Tato funkce inicializuje pole tak, že v něm bude vzestupně seřazená, respektive neklesající posloupnost hodnot. Výsledek může být pokaždé jiný. Výsledkem bude náhodně vygenerovaná, ale neklesající posloupnost.


Nerostoucí posloupnost

Tato funkce inicializuje pole tak, že v něm bude sestupně seřazená, respektive nerostoucí posloupnost hodnot. Výsledek může být pokaždé jiný. Výsledkem bude náhodně vygenerovaná, ale nerostoucí posloupnost.


Náhodná posloupnost

Tato funkce inicializuje pole tak, že v něm bude náhodná, neseřazená posloupnost hodnot.


Test seřazeného pole

Napište funkci pro testování inicializovaných polí. Funkce bude vracet kladné číslo, když bude zadané pole tvořit rostoucí nebo neklesající posloupnost. Pokud bude zadané pole tvořit klesající nebo nerostoucí posloupnost, bude funkce vracet záporné číslo. Pokud prvky pole netvoří ani neklesající ani nerostoucí posloupnost, bude funkce vracet nulu.

Použijte tuto funkci pro otestování výsledků předchozích funkcí.

neklesajici(pole, 10, 3);
pole --> 0 1 1 2 3 3 4 4 4 5
Příklad generování neklesající posloupnosti s maximálně 3 duplicitními hodnotami každého klíče.
nerostouci(pole, 10, 2);
pole --> 9 7 5 5 4 3 3 1 1 0
Příklad generování nerostoucí posloupnosti s maximálně 2 duplicitními hodnotami každého klíče.
nahodne(pole, 10, 0);
pole --> 8 4 7 6 3 1 9 2 0 5
Příklad generování náhodné posloupnosti bez duplicitních klíčů.

Návod pro generování duplicitních klíčů u náhodného pole

Méně přesná varianta

V jednom průchodu nastavte do všech prvků pole zcela náhodné hodnoty (například rand()%MOJE_MAXIMUM) a neřešte duplicity. V dalším průchodu pak duplicity dotvořte tak, že se hodnota každého prvku zkopíruje zadaný počet krát. Například rand()%pocetDuplicit krát na náhodné pozice v poli pole[rand()%n] (% znamená operaci modulo).

U této varianty může dojít k tomu, že u některého čísla bude počet duplicit větší než bylo zadáno, protože konstrukce rand()%MOJE_MAXIMUM může produkovat duplicity už při prvotní inicializaci. Toto se dá ošetřit dodatečnou kontrolou.

Přesnější varianta

Vyrobte si pomocné pole stejné délky jako inicializované pole. Nastavte v něm do každé položky hodnotu pocetDuplicit. Nastavení prvku v pole[i] pak bude pom=rand()%delkaPole, přičemž v pomocném poli se sníží hodnota na tomto indexu pom o jedničku. Pokud v pompole[pom] už byla nula, tato hodnota už nejde použít a musíte to zkusit znova.