Programozás(A szakirány) II. beadandó feladat 2014.05.05.
Farkas András HP6S15
[email protected]
1. csoport Veszprémi Anna / Hudoba Péter
Feladat: Egy szöveges állományban bekezdésekre tördelt szöveg található. Egy bekezdés egy vagy több nem üres sorból áll. A bekezdéseket üres sorok vagy az állomány eleje illetve vége határolja. - Melyik a leggazdagabb bekezdés, azaz hányadik az a legalább három soros bekezdés, ahol a legnagyobb a szavak számának és a sorok számának hányadosa?
Megoldási terv: Specifikáció: A = ( f: InFile(K), x: Eredmény) Állapottér átalakítása olyan felsorolóra amely a bekezdések számunkra fontos tulajdonságait adja meg:
A = (t: Enor(Bekezdés), x:Eredmény) Bekezdés = rec(sordb: N, szdb: N, sorsz: N) Eredmény = rec(sorsz: N, hanyados: R) Ef = (t=t') Uf = ( (l),x.hanyados,x.sorsz =
MAX e ∈t ' e.hanyados ) e.sordb⩾3
Absztrakt program: Feltételes Maximumkeresés: f(i) ~ e.hanyados β(i) ~ e.sordb > 2
Felsoroló: enor(Bekezdes)
First(), Next(), Current(), End()
F: InFile(string) sor: StringStream st: Status akt: Bekezdés vége: L
First() ~ akt.sorsz=0 st,sor,f: read() Next() Next() ~ ld. kiemelve Current() ~ ret: akt End() ~ ret: vege
A Next() műveletnek a következő feladatot kell végrehajtania:
Adott egy sorokra tördelt szöveges állomány, ahonnan már kiolvastuk az első sort (ez van a sor változóban, ha sikeres volt ez a korábbi olvasás, egyébként st=abnorm), illetve ezen előző bekezdés sorszáma (akt.sorsz); és a soron következő bekezdést kell feldolgoznunk. Először átolvassuk a bekezdés előtti üres sorokat, ha nincs több nem üres sor, akkor vége változót igazra állítjuk. Ha találunk, akkor a vége változó hamisra áll, az akt.sorsz értékét eggyel növeljük, és az akt többi mezőjét inicializáljuk, majd kitöltjük a következők szerint: A külső tételnek a bekezdés sorainak számára, illetve szavainak számára van szüksége. A bekezdés sorait soronként olvasva az akt.sordb-t mindig eggyel növeljük, illetve a sorokon belül megszámoljuk hogy hány valamilyen whitespace-l elválasztott szó szerepel, az akt.szdb-t mindig eggyel növelve. A bekezdés feldolgozása végén vagy a bekezdést követő (első) üres sort olvassuk be utoljára (ami bekerül a sor változóba), vagy elértük az állomány végét (st=abnorm).
ANext = (f: InFile(String), sor: String, st: Status, vége: L, akt: Bekezdés) EfNext = ( f = f ' ∧sor=sor 1∧st=st 1∧akt=akt 1 ) 2, 2, select (st=abnorm∨sor ≠üres)∧(vége=( st 2=norm)) ˄ UfNext = ( st sor f '= 1, sor ∈( sor f ' ) 1 ¬vége → akt.sorsz =akt . sorsz+1 ˄ ∑1 ˄ akt.sordb , st , sor , f = sor ∈( sor 1 , f ' ) st=norm∧sor≠üres akt.szdb , st , sor , f =∑ szavak1( sor ) ) sor ∈( sor , f ' )
Implementáció: Program váz: A program több állományból áll: main.cpp, enor.h, enor.cpp, misc.h. main.cpp
enor.h
enor.cpp
misc.h
int main()
struct Bekezdes enum Status class Enor Enor() ~Enor() void First() Bekezdes Current() bool End()
void Read() void Next()
struct Eredmeny bool cconvert() void bfflush()
Függvények kapcsolódási szerkezete:
Felsoroló osztálya:
class Enor{ private: std::ifstream f; std::stringstream sor; Status st; Bekezdes akt; bool vege; void Read(); public: Enor(const std::string &str); ~Enor(){f.close();} void First() {Read(); Next();} void Next(); Bekezdes Current() const { return akt;} bool End() const { return vege;} };
A szöveges állomány soronkénti olvasását a getline(f, sor) utasítás végzi, amely a Read() metódusba van beágyazva úgy, hogy stringstream típusú adatként adja vissza, illetve beállítja az olvasás st státuszát. A stringstream típusú sor szavainak olvasása a >> operátorral történik. Akkor üres a sor, ha sztringként értelmezve az üres sztringgel egyenlő. A megvalósításban a szavak() függvény nem került önálló alprogramba.
Használat: A program a feldolgozandó fájl elérési útjának bekérésével indul. Amennyiben nem létező fájlt adunk meg, a program a nevet újra bekéri. A feladat elvégzése után az eredmény az alapértelmezett kimenetre íródik ki, majd a program megkérdezi hogy szeretnénk-e tovább (újra) lefuttatni. Eldöntendő kérdésekre a program 'nem'-ként az N, n, 0 karaktereket fogadja el, 'igen'-ként pedig bármi mást.
Tesztelési terv A megoldásban egy külső feltételes maximumkeresés és kettő darab számlálás szerepel.
Külső szint: 1. Nincs megtalálandó bekezdés, mert egyik sem áll legalább 3 nem üres sorból. ures.txt 2. Egyetlen, több mint 3 soros bekezdés van a fájlban. egy.txt 3. Több megfelelő bekezdésből kell a megfelelőt megtalálni, ami mögött még van kevesebb mint 3 soros. sok1.txt / sok2.txt 4. A megfelelő bekezdés a legeslegutolsó, de előtte van jóval „szógazdagabb” de csupán 2 soros bekezdés. utolso.txt 5. A fájl csak whitespacekből és újsorjelekből áll. Ekkor a program megtalálja a legalább 3 soros „bekezdést”, és a hányados nulla. buta.txt
A felsoroló szintje: Ezek az esetek arra vannak kihegyezve hogy a program a szabályoknak megfelelően viselkedik-e extra üres sorok illetve kizárólag whitespaceket tartalmazó sorok esetén. 1. A fájl nem tartalmaz üres sort. egy.txt 2. A fájl eleje / vége üres sorokból áll. sok1.txt 3. Egy-egy bekezdés belsejében van 'üres' tehát csak whitespace-t tartalmazó sor. sok2.txt 4. A fájl csak whitespacekből és újsorjelekből áll. Ekkor a program megtalálja a legalább 3 soros „bekezdést”, és a hányados nulla. buta.txt A felsorolt esetek a fehérdoboz tesztet is lefedik a program összes függvénye számára.