Programozás(A szakirány) II. beadandó feladat 2014.05.05. Farkas András HP6S15 fafee@fafeecorp.com 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.sordb 3 e.hanyados ) Absztrakt program: Feltételes Maximumkeresés: f(i) ~ e.hanyados β(i) ~ e.sordb > 2
Felsoroló: enor(bekezdes) F: InFile(string) sor: StringStream st: Status akt: Bekezdés vége: L First(), Next(), Current(), End() 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).
A Next = (f: InFile(String), sor: String, st: Status, vége: L, akt: Bekezdés) Ef Next = ( f = f ' sor=sor 1 st=st 1 akt=akt 1 ) Uf Next = ( st 2, sor 2, f '= select sor (sor 1, f ' ) (st=abnorm sor üres) (vége=(st 2 =norm)) vége akt.sorsz=akt 1. sorsz+1 akt.sordb,st,sor, f = 1 sor (sor 1, f ' ) st=norm sor üres akt.szdb, st, sor, f = szavak (sor) sor (sor 1, 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.