FormatMachine
Selle ülesande eesmärk on kirjutada olekumasin, mis aitab meid teksti korrastamisega. Sisendiks saame näiteks sellise tekstijupi:
This text (all of it )has occasional lapses .. .in punctuation( sometimes,pretty bad ; sometimes ,not so). ( Ha ! )Is this :fun ! ? ! Or what ?
Ja me tahaks, et tulemuseks oleks ilus korrastatud tekst:
This text (all of it) has occasional lapses... in punctuation (sometimes, pretty bad; sometimes, not so). (Ha!) Is this: fun!?! Or what?
Korrastatud tekst vastab järgmistele nõuetele:
- Sõnade vahel on täpselt üks tühik.
- Kirjavahemärkidena arvestame selles ülesandes järgmiseid: koma, koolon, semikoolon, punkt, hüüumärk ja küsimärk. Eraldi käsitleme ka sulgusid.
- Sõna ja temale järgneva kirjavahemärgi vahel ei ole tühikut, aga kirjavahemärgi ja temale järgneva sõna vahel on: "Tere, Maailm!"
- Kirjavahemärkide vahel ei ole tühikut, näiteks "Mis asja?!".
- Avav sulg käitub vastupidiselt teistele kirjavahemärkidele: sellel on ees tühik, aga järel mitte.
- Lõppev sulg käitub põhimõtteliselt nagu teised kirjavahemärgidki.
- Rea alguses ei ole ühtegi tühikut! (Uue rea sümbol on
\n
). NB! Ka esimesel real ei tohiks olla alguses ühtegi tühikut.
Kuidas seda lahendada
Me oleme ainult paari miljoni euro eest saanud sellise üldise raamistiku seda tüüpi ülesannete lahendamiseks. Raamistiku töö on sisendit kuskilt lugeda ja tähthaaval meie olekumasinale sööta. Meie olekumasin annab iga tähe jaoks vastuseks sõne (mis võib ka olla tühi), millega tuleks antud täht asendada. Raamistiku kood on järgmine:
public class FormatMachine { public String process(char c) { // TODO: Asendada millegagi, mis midagi asjalikku teeb. return "" + c; // ehk Character.toString(c) } // Masina kasutamine public static void main(String[] args) { String input = "This text (all of it )has occasional lapses .. .in\n" + " punctuation( sometimes,pretty bad ; sometimes ,not so).\n" + "\n" + "( Ha ! )Is this :fun ! ? ! Or what ?"; System.out.println(cleanUp(input)); } public static String cleanUp(String s) { StringBuilder sb = new StringBuilder(); FormatMachine machine = new FormatMachine(); for (char c : s.toCharArray()) sb.append(machine.process(c)); return sb.toString(); } }
Me oleme väga tänulikud, sest nüüd jääb ainult implementeerida olekumasina meetod process
.
Kui raamistiku kirjeldus on segane, siis proovige kõigepealt katsetamise teel aru saada, mis ta teeb. Käivitage ülalolev kood, kui process
on täpselt nii nagu ta üleval on. Tehke siis väikesed muudatused. Proovige näiteks, mis juhtub, kui process teeb ainult return " " + c;
, jne. Oluline on kõigepealt aru saada raamistikust, sest me oleme sinna palju raha investeerinud ja seda enam muuta ei saa.
NB! Kui ülesanne ise tundub raske, siis alustage ikkagi lihtsamate testjuhtumitega:
Üks kaks kolm neli viis
Tere , maailm !
Tere ,maailm ! !
Järgmisena proovige mõned testid sulgudega. Ja lõpuks peab reavahetust käsitlema ('\n'), et meie esialgne näide ka töötaks.
Kui ka peale pikemat pusimist jääd hätta, siis .
FormatMachine.process
peab mõned etteantud sümbolid tagastama nii, nagu nad on, mõned tagastama koos tühikuga, mõned sümbolid hoopis "alla neelama".- Kahjuks ei piisa otsuse tegemiseks ainult sümboli uurimisest.
- Vaja teada ka sümboli konteksti.
- Kuigi korraga antakse ette vaid üks sümbol, ei keela keegi
FormatMachine
isendil jätta meelde mingit infot juba nähtud sümbolite kohta. - Näiteks võiks jätta meelde, mis "liiki" sümboliga viimati tegeldi ja võrrelda seda käesoleva sümboli liigiga.
Allikas
Ülesanne on inspireeritud Victor Eijkhout'i juhendist "A Lex Tutorial". Võib-olla seal olev lahendus on abiks, aga sealsest kontekstist aru saamine võib rohkem aega nõuda, kui ülesanne otse lahendada.