Autorské riešenie
Túto úlohu môžeme riešiť dvoma spôsobmi. V prvom prípade budeme prechádzať zadaným textom, analyzovať znak po znaku, aby sme zistili, či sme našli oddeľovať slov (a zvýšili počet nájdených slov) alebo oddeľovač viet (a vypočítali náročnosť vety). Druhá možnosť je upraviť text tak, aby ho bolo možné jednoducho rozdeliť na vety a vo vetách spočítať slová. Tento spôsob je výhodnejší v tom, že vo väčšej miere budeme používať funkcie jazyka a menej sa spoliehať na našu analýzu. Je tak menej pravdepodobné, že v riešení urobíme chybu. Pozrime sa bližšie na tento spôsob. Aby sme mohli vypočítať náročnosť testu, potrebujeme vedieť:
Situáciu nám komplikuje fakt, že: "Pred a za slovami či vetami je viacero medzier alebo voľných riadkov. Bodky, výkričníky, otázniky, čiarky, dvojbodky či úvodzovky sú na tom ešte horšie. Pri nich navyše občas medzery chýbajú. " Podľa tohto opisu by mohol text vyzerať napr. takto:
Takto neporiadne napísaný text by podľa typografických pravidiel mal vyzerať nasledovne:
Text potrebujeme rozdeliť na vety a v každej vete identifikovať počet slov. Slová vo vetách sú oddelené medzerou a vety sú oddelené jedným zo znakov: .!?: Potrebovali by sme text upraviť tak, aby sme ho vedeli rozdeliť na vety a v každej vete spočítať slová. Oddeľovačom viet môže byť bodka a oddeľovačom slov medzera. Napríklad takto:
Takto upravený text ľahko rozdelíme na vety a v každej vete ľahko spočítame slová. Funkcia na úpravu textu môže vyzerať nasledovne: # Python def uprav_text(text): # všetky oddeľovače slov nahradíme medzerou text = text.replace('\n', ' ') text = text.replace('„', ' ') text = text.replace('“', ' ') text = text.replace(',', ' ') # všetky oddeľovače viet nahradíme bodkou text = text.replace('!', '.') text = text.replace('?', '.') text = text.replace(':', '.') # viaceré medzery za sebou nahradíme jednou while text.find(' ') != -1: text = text.replace(' ', ' ') # ak pri nejakej bodke ostala medzera, vymažeme ju text = text.replace('. ', '.') text = text.replace(' .', '.') # ak na konci textu ostala bodka, vymažeme ju if text[-1] == '.': text = text[:-1] # ak na koncoch textu ostala nejaká medzera, vymažeme ju text = text.strip() return text Ak už máme text upravený, môžeme vypočítať jeho náročnosť. # Python def narocnost_vety(veta): pocet_slov = veta.count(' ') + 1 narocnost = pocet_slov ** 1.1 return narocnost def narocnost_textu(text): text = uprav_text(text) narocnost = 0 vety = text.split('.') for veta in vety: narocnost = narocnost + narocnost_vety(veta) return narocnost V riešení do veľkej miery využívame textové funkcie. Pri úprave sme nahrádzali časti textu (''.replace()), vyhľadávali v texte (''.find()), vyberali časti reťazcov (''.[:-1]) alebo odstraňovali netlačiteľné znaky z jeho koncov (''.strip()). Upravený text sme rozdelili na vety (''.split()) a v každej vete sme spočítali medzery (''.count()), aby sme zistili počet slov. Manipulácia s textami je pre počítač vo všeobecnosti náročná. Ide hlavne o prípady, keď spracovávame rozsiahle texty. Programovacie jazyky preto často poskytujú aj iné, efektívnejšie spôsoby ako s textami pracovať. Jedným z nich sú regulárne výrazy. Ak by sme v riešení využili regulárne výrazy, celé riešenie môže vyzerať nasledovne: # Python import re def narocnost_vety(veta): pocet_slov = veta.count(' ') + 1 narocnost = pocet_slov ** 1.1 return narocnost def uprav_text_na_vety(text): # všetky postupnosti oddeľovačov slov nahradíme medzerou text = re.sub('[ \n„“,]+', ' ', text) # zbavíme sa medzier na začiatku a oddeľovača vety # (s pripadnými medzerami) na konci textu text = re.sub('^ *(\S.*\S) *[!?:\.] *$', '\\1', text) # rozdelíme text na vety podľa oddeľovačov viet, # ktoré môžu mať okolo seba medzery vety = re.split(' *[!?:\.] *', text) return vety def narocnost_textu_re(text): vety = uprav_text_na_vety(text) narocnost = 0 for veta in vety: narocnost = narocnost + narocnost_vety(veta) return narocnost Túto verziu riešenia úlohy sme uviedli len preto, aby sme ukázali, že každé riešenie je možné ešte vylepšiť. Ak vás použitie regulárnych výrazov zaujalo, viac sa o ňom dozviete napr. na: Vaše zaujímavé riešenia a najčastejšie chyby Pri riešení úlohy ste sa snažili rozložiť zadaný text na vety - využili ste to, že veta končí niektorým zo znakov ., :, ?, !. Takto získané vety ste prechádzali a ako oddeľovače slov ste využili čiarky a medzery. Zabudli ste však vhodne spracovávať úvodzovky, ktorými končila veta priamej reči - výsledkom bol vyšší počet viet. Niektorí z vás nevyriešili situáciu s viacriadkovým textom - program fungoval správne len vtedy, ak išlo o jeden riadok. Tím HairyElephants ako jediný z tímov využil pri riešení úlohy regulárne výrazy. V autorskom riešení sme uvažovali slovenské úvodzovky „“, ale vo vašich riešeniach sme akceptovali ľubovoľné. |
||||||||||
© Univerzita Pavla Jozefa Šafárika v Košiciach, Prírodovedecká fakulta, Ústav informatiky palmaj (zavinac) upjs.sk |