====== Cvičení 9, Fronta, Stavový automat ======
===== náplň cvičení =====
==== Úloha 1 Fronta ====
* Přeměňte řešení úlohy 3 Flood fill z cvičení 8 na frontu.
* Postupnou animací zjistěte jak se změnilo vyplňování prostoru
* Zjistěte, zda potřebuje více paměti zásobník, nebo fronta
==== Úloha 2 Komentáře - rozšíření ====
* Upravte program na odstraňování komentářů z přednášky tak:
* aby program bral v úvahu řetězce začínající a končící znakem '
* aby správně interpretoval znaky \' a \"
* aby pokud řádka končí znakem \ dovedl řetězec prodloužit přes více řádek
* Program otestujte na následujících datech
a='b\'c#d' #e
i="j\"k'l#m" #n
* Program z přednášky:
def preskoc_komentare(line):
# vytiskne obsah souboru 'f' s vynechanymi komentari
stav=0 # počáteční stav automatu
for c in line: # přečti jeden znak
if stav==0: # počáteční stav
if c=="#": # začátek komentáře
stav=1
continue
elif c=='\"':
stav=2 # začátek řetězce
elif stav==1: # 1="komentar"
continue
elif stav==2:
if c=='\"':
stav=0
print(c,end="") # vytiskni znak
i=input()
preskoc_komentare(i) # nacti radku a preskakuj
==== Úloha 3 Kontrola reálného čísla ====
* Reálné číslo v pythonu je zadána touto [[https://cs.wikipedia.org/wiki/Rozvinut%C3%A1_Backusova-Naurova_forma|EBNF]] gramatikou:
floatnumber ::= pointfloat | exponentfloat
pointfloat ::= [intpart] fraction | intpart "."
exponentfloat ::= (intpart | pointfloat) exponent
intpart ::= digit { digit }
fraction ::= "." digit { digit }
exponent ::= ("e" | "E") ["+" | "-"] digit { digit }
digit ::= "0"..."9"
* Vymyslete a naprogramujte stavový automat, který bude zjišťovat, zda je řetězec na řádce reálným číslem.
==== Úloha 4 Obsahy závorek ====
* Uvažujme řetězec obsahující závorky () a [].
* Napište program, který bude testovat, zda je výraz správně uzávorkován a zjistí text uvnitř závorek
* Závorky mohou být do sebe vnořeny a pak text patří do poslední úrovně závorek
* Program tedy text:
aa[bb(cc)dd(ee)fff[gggg]]hhh
* převede na výstup:
()cc
()ee
[]gggg
[]bbddfff
* písmena 'aa' a 'hhh' se zahodí, nejsou uvnitř žádných závorek
===== domácí práce =====
==== Lehká varianta:====
* Napište program **students.py**, který načtěte databázi adres z textového souboru, jehož jméno je první argument programu, podle níže uvedeného formátu:
zaznam ::= cele_jmeno ";" studium
cele_jmeno ::= jmeno "(" jmena ")" "{" rodne_prijmeni "}" prijmeni |
jmeno "(" jmena ")" prijmeni |
jmeno "{" rodne_prijmeni "}" prijmeni |
jmeno prijmeni
jmeno, rodne_prijmeni, prijmeni ::= pismeno { pismeno }
jmena ::= jmeno { ","jmeno }
pismeno ::= "a"..."z"|"A"..."Z"
studium ::= typ "," rocnik "," obor
typ ::= ( "Bc." | "Ing." | "Ph.D." )
rocnik ::= cislo { cislo }
cislo ::="0"..."9"
obor ::= pismeno { pismeno }
* Jeden záznam je vždy na jednom řádku, pokud záznam neodpovídá formátu data celý řádek se zahodí.
* Mezi jednotlivými položkami záznamu může být i několik mezer.
* Pokud záznam odpovídá formátu, vytiskne se na výstup informace o záznamu ve tvaru:
* pokud má jen jedno křestní jméno:
* příjmení, křestní jméno, obor, typ
* pokud má více křestních jmen (v tomto případě David a Václav, vytisknou se jen iniciály a tečka):
* příjmení, D. V., obor, typ
* Program odevzdejte do HW09.
* Výstup programu pro vstup ze souboru {{courses:b3b33alp:cviceni:studium_test1.txt|studium_test1.txt}} bude:
Novak, Jaroslav, oi, Bc.
Novak, J. D., kybernetika, Ph.D.
Novy, J. M. Z., robotika, Ing.
Nova, Jarmila, robotika, Ing.
Novak, Jara, kybernetika, Ph.D.
Novotny, J. D. I., robotika, Ing.
Nowotnny, Y. D. Y., robotika, Ing.
==== Těžká varianta:====
* Proveďte předzpracování (pre-processing) programu v jazyce C.
* Ve programu zadaném jako parametr Vašeho programu proveďte textové záměny:
* ''#define name replacement''
* ''#define name(x,y,z) replacement''
* ''#undef aa''
* ''#ifdef aa''
* ''#endif''
* odstraňte komentáře
* Funkčnost těchto příkazů
* ''#define řetězec zbytek_do_konce_řádky''
* nadefinuje náhradu řetězce novým řetězce, který je definován za prázdnými znaky řetezce až do konce řádky
* ''#define řetězec( seznam parametrů ) zbytek_do_konce_řádky''
* nadefinuje náhrazu řetezce se zadanými parametry. Při náhradě budou parametry ve zbytku řádky nahrazeny zadanými řetězci
* direktiva '#define' umožňuje volání dalších direktiv, tj. v řetězci ''zbytek_do_konce_řádky'' mohou být volána další makra
#define MIN_VALUE -1.0f
#define normalize(_x) _x - MIN_VALUE
* ''#undef řetězec''
* zruší definici náhrady řetězec
* ''#ifdef řetězec''
* pokud je definována náhrada řetězec, pak následující řádky jsou kopírovány na výstup. Pokud není, jsou všechny řádky do příkazu ''#endif'' zahozeny
* ''#endif''
* ukončuje platnost předchozího příkazu ''#ifdef''
* **Upřesnění zadání:**
* Pokud řádek obsahuje definici výše uvedených příkazů, pak od začátku řádku do znaku # mohou být pouze mezery, nebo znak TAB.
* Každý řádek může obsahovat nejvýše jeden příkaz
* Při zadání senzamu parametrů příkazu #define nesmí být mezi koncem řetězce a znakem '(' mezera.
* Příkazy #ifdef mohou být vnořeny
* Náhrada se provádí v textu programu, který není komentářem a který není v řetězci
* Komentáře v jazyce C jsou:
* od znaků '//' do konce řádky
* od znaků '/*' do znaků '*/' i přes více řádků
* předpokládejte, že komentáře nebudou vzájemně vnořeny, tedy situace /* /* */ */, nebo /* // */ nenastanou
* veškerý text komentářů bude odstraněn a neobjeví se na výstupu
* Řetězce v jazyce C začínají znakem " nebo ' a končí stejným znakem. Řetězce v této úloze nemohou být přes více řádek, ale mohou obsahovat sekvence \' a \".
* Program **preprocessing.py** načte soubor zadaný jako vstupní parametr a vytiskne na výstup zpracovaný výstup, který obsahuje pouze aktivní řádky.
* Program odevzdejte do HW09.
=== Příklad ===
* Následující vstup
#define MIN_VALUE -1.0f
#define _normalize(_x) ff((_x) - MIN_VALUE)
#define ff cos
float last_value = get_value();
#ifdef output
// Print if defined
std::cout << "Normalized: " << _normalize(last_value);
#endif
auto y = 2.0f * _normalize(atan2(last_value,-last_value)+0.5f);
#define MIN_VALUE -10.0f
#undef ff
auto y2 = 2.0f * _normalize(last_value);
* převede preprocessor.py na následující výstup:
float last_value = get_value();
auto y = 2.0f * cos((atan2(last_value,-last_value)+0.5f) - -1.0f);
auto y2 = 2.0f * ff((last_value) - -10.0f);
* direktivy #define, #ifdef, #endif, #undef se netisknou, příkaz std::cout je v neaktivním bloku, v ostatních řádcích jsou pak nahrazená makra.