Lab 1 - Reguljära uttryck och läsning + skrivning

Inledning

I denna lab ska ni skriva framföallt skriva kod där ni utnyttjar reguljära uttryck för texthantering i Java. Den innehåller även övningar på läsning och skrivning med hjälp av klassen Scanner och format-metoden.

I labben kommer ni att jobba med ett antal textfiler, formatterade på olika sätt. Samtliga filer innehåller svensk text från Europaparlamentets proceedings. Dessa kan ni hämta här och spara ner till er eget konto.

Uppgift 1 - regexp-övningar

I denna uppgift ska ni lösa ett antal strängmatchningsuppgifter. I samtliga uppgifter ska ni applicera dem på filen testtext_short_raw.txt, som innehåller några meningar från Europaparlamentets proceedings, där varje mening står på en egen rad.

Ni skapa en klass MyMatcher, som innehåller ett antal metoder för att hantera strängar, en för varje deluppgift nedan. Det finns en klass TestMyMatcher, som testar era metoder. Ladda ner den! Metoderna i MyMatcher ska ta emot en mening i taget, och returnera det som matchar. TestMyMatcher läser in hela testtexten med hjälp av Scanner-klassen, och skickar varje mening till de olika matchningsmetoderna, för att sedan skicka tillbaka matchningen.

Samtliga uppgifter ska lösas med hjälp av reguljära uttryck. Ni kan använda både de metoder i String-klassen som tar regexps som argument, till exempel replaceAll och split, och metoder i klasserna Matcher och Pattern i java.util.regex. Läs mer om vilka metoder som finns i Javas API.

Skriv en metod för varje uppgift, där varje metod tar en mening som indata

  1. Hitta och skriv ut alla ord som skulle kunna vara adjektiv i superlativ, det vill säga ord med ändelsen "sta" eller "ste", till exempel "största" och "finaste".
  2. Hitta och skriv ut alla klockslag som anges enligt 24-timmarstandarden, det vill säga "hh.mm", som "09.08" eller "23.14". Ert uttryck ska endast godkänna giltiga klockslag, ej till exempel "25.02", "11.68" eller "1.34".
  3. Dela upp meningen i segment separerade av kolon, kommatecken eller tankstreck, och skriv ut ett per rad. För meningen "Hej, sa Kim - min kompis." ska ni skriva ut de tre segmenten "Hej", "sa Kim" och "min kompis.". Se till att eventuella mellanslag inte kommer med i segmenten. Om en mening ej innehåller kolon, kommatecken eller tankstreck ska hela meningen skrivas ut som ett segment. Observera att en förenklad syntax använts i exempelmeningarna, så att tecknet tankstreck skrivits som ett bindesstreck, "-".
  4. Tokenisera meningen och skriv ut den. Att tokenisera innebär att man separerar ord och skiljetecken, det vill säga lägger till mellanslag mellan dem. Till exempel kan man tokenisera meningen "Hej, sa han som kallas 'Lill-kalle'." till "Hej , sa han som kallas ' Lill - kalle ' .". Ofta försöker man undvika att till exempel dela upp förkortningar som innehåller punkter, som "t.ex.", men det kan ni bortse ifrån i denna uppgift och göra en enkel tokenisering, där det är ett mellanslag framför och efter varje skiljetecken. Undvik dock dubbla mellanslag.
  5. Gör om meningen till rövarspråket och skriv ut den. I rövarspråket byts alla konsonanter ut till konsonant-o-konsonant, till exempel "huset" till "hohusosetot". (Ni kan läsa mer på Wikipedia, men behöver inte bry er om undantagen)

För deluppgift 1 och 2 ska ni även rita och lämna in den finita automat som motsvarar ert reguljära uttryck för superlativ respektive klockslag. Om ni vill kan ni göra det för hand på papper. Ni kan förenkla automaten genom att använda er av teckenklasser på bågarna, till exempel skriva "[abc]" på en båge istället för att göra tre separata bågar med "a", "b" resp. "c".

Uppgift 2 - matcha i taggad text

I den här uppgiften ska ni jobba på taggad text, som finns i filen testtext_tagged.txt. Varje rad innehåller en mening med taggad text, där varje ord och tagg separeras med "/", till exempel "hunden/NN sover/VB ./PUNCT". Alla ord i filen är omjorda till gemener, och taggarna är skrivna med versaler.

Ni skriva två klasser, en klass som inehåller en metod med lösningen till varje uppgift samt eventuella hjälpmetoder, och en klass med ett testprogram. Ge dessa klasser lämpliga namn!

I följande uppgifter ska ni matcha olika uttryck med hjälp av taggar, och ibland också med hjälp av ord. I det här fallet ska era metoder ta emot en hel text (som ni läser in från fil i ert testprogram). Använd metoderna i klasserna i java.util.regex för att lösa dessa uppgifter.

I de här uppgifterna ska ni presentera resultatet som en frekvensordlista, där varje uttryck ni hittat presenteras tillsammans med sin frekvens i texten, det vill säga hur många gånger den förekommer. För att skapa er frekvensordlista ska ni använda någon av Javas klasser för hashtabeller, till exempel HashMap. Fundera på vilka metoder som kan vara lämpliga att ha i er klass för att hantera frekvensordlistor och deras utskrift. Använd "format" när ni skriver ut era frekvenslistor, för att skapa raka marginaler. Ni kan utgå från någon rimlig maxlängd för ord. Ett exempel på hur utskriften skulle kunna se ut för uppgift två nedan är:

  DT   87
  PM   35
  NN  215
...

Skriv ut frekvensordlistor för följande uttryck:

  1. Treordsnominalfraser i superlativ som består av en artikel, följd av ett adjektiv i superlativ och ett substantiv. För att uppnå detta ska ni hitta ett ord som är en artikel (DT), följt av ett adjektiv (JJ) som slutar på "sta" eller "ste", följt av ett substantiv (NN). I den här uppgiften kan ni skriva ut hela treordssekvensen inklusive taggarna i frekvensordlistan. Taggarna behöver alltså inte rensas bort, utan det är OK att ha till exempel "den/DT största/JJ respekt/NN 1" i listan.
  2. Ordklasser som följer efter prepositioner. Här ska enbart ordklassen på ordet direkt efter en preposition (PP) tas med, ej några ord eller andra taggar.
  3. Adjektiv som följer efter ett annat adjektiv separerat av kommatecken eller "och". Som "gott" i "mumsigt, gott godis" eller "nyttigt och gott mellanmål". Titta efter i filen för att se hur kommatecken respektive "och" taggas. I den här uppgiften ska ni rensa bort taggar, "och", kommatecken, och det första adjektivet, så att enbart det andra adjektivet kommer med.

Uppgift 3 - ta fram statistik från text

I den här uppgiften ska ni framförallt använda Scanner för att läsa in en text, och format för att skriva ut statistik. Om ni vill kan ni även använda reguljära uttryck för vissa deluppgifter. Målet med uppgiften är att ta fram statistik för olika aspekter av en text och presentera statistiken på ett snyggt sätt. Resultatet av ert program ska vara en utskrift enligt följande (observera att statistiken nedan inte stämmer med era förväntade resultat):
Texten innehåller 4858 ord i 311 meningar, vilket ger en medelordlängd på 15.62

Statistik över ordlängd i tecken:
Medelordlängd:            5.32
Längsta ord:                26
kortaste ord:                1
vanligaste ordängd:          3

Antal förekomster av de ord som förekommer minst 75 gånger, samt deras procentandel av alla ord:
  107       2.20      det
  100       2.06      för
  173       3.56      att
  ...

Vilken statistik ni ska beräkna framgår av utskriften ovan. Ord ska filtreras ut genom att enbart behålla tokens som innehåller minst en bokstav eller siffra. Detta innebär att skiljetecken inte ska beaktas. Använd filen testtext_tok.txt. för att testa ert program. Återigen står varje mening på en rad, och i det här fallet är texten redan tokeniserad. Utskriften ska formatteras så att decimaltal skrivs ut med två decimaler, och att marginalerna är raka för olika typer av information.

För att lösa denna uppgift ska ni skriva två klasser, en som innehåller de metoder som behövs för att lösa uppgiften och en testklass, där ni tar emot ett filnamn, och anropar relevanta metod(er) i den andra klassen. En del i uppgiften är att dela upp lösningen i lämpliga metoder. Sträva efter att varje metod ni skriver ska ha en tydlig uppgift, och undvik att upprepa (nästan) identisk kod på flera ställen. Tänk även igenom vilka instansvariabler ni behöver i era klasser och vilka variabler som kan vara lokala i de olika metoderna. För att öva på Scanner, format och hashtabeller, samt för att ha en god kodkvalitet, ställs följande krav på er lösning:

  • Inläsningen av orden från fil ska göras enbart med hjälp av Scanner klassen. Använd Scanner både för att läsa rader med meningar, och för varje mening för att läsa ord. (ett annat bra alternativ hade varit att använda split i String-klassen, men här ska ni öva på Scanner)
  • Ord och frekvenser ska lagras i någon av Javas klasser för hashtabeller, till exempel HashMap.
  • Använd format för utskriften, för att hantera avrundning samt snygga marginaler.
  • All information ni lagrar, ska lagras som variabler med tydliga namn och med lämplig typ.

Examination

Bifoga följande i ett mail till er labassistent:

  • All källkod för de tre uppgifterna, inklusive den givna koden
  • Utskrifter från era testprogram
  • Utskrift eller handskrift som visar finita automater för uppgift 1.1 och 1.2.

Checklista för inlämnat material:

  • Uppfyller programmet kravspecifikationen?
  • Har ni använt reguljära uttryck för att lösa uppgifterna när det krävs?
  • Är alla delar inlämnade?
  • Används lämpliga och tydliga namn för klasser, metoder och variabler?
  • Följer koden kodkonventionerna?
  • Är koden enhetligt indenterad?
  • Används en rimlig åtkomstnivå för klasser, variabler och metoder?
  • Har ni en bra uppdelning i metoder, framförallt i uppgift 3?



Skapad för 5LN446, 2013 av Sara Stymne