[zapo] 7.2. 14oo

THX
Matfyz(ák|ačka) level I
Příspěvky: 8
Registrován: 7. 2. 2006 12:44
Typ studia: Informatika Bc.
Kontaktovat uživatele:

[zapo] 7.2. 14oo

Příspěvek od THX »

Tak dnes prisiel Obdrzalek jr.
Zadanie sa mozno zda zlozite, ale nakoniec to bolo celkom jednoduche, ja som to nastastie dal, aj ked som mal na zaciatku uplne zakladne problemy s nacitanim vstupu. Tak toto som si poznamenal priamo na teste:
zadanie: 2.5h a musi to ficat, nefici = nedobre
Konecny automat: ma stavy, prechadza medzi nimi podla vstupu (a aktual stavu a sype nieco na vystup)
proste klasika avtomat kalasnikova
automat pracuje nad jednotlivimi znakmi (po jednom znaku)

zoznam stavov : vstupy : cielovy stav : vystup
stav, stav2, ... stavN: AGEW : stav : A
stav je identifikator, stavy oddelene ciarkou

napr. stav
START: AEIOUY : SAMOHL : A
vstup: a-zA-Z0-9 , proste iba pismena a cisla
.... na niektorych miestach budu moct byt hviezdicky, napr. START: AEUIUY : SAMOHL : *
hviezda namiesto vystupu: * znamena prvy znak na ktory sa chytil, t.j. v tomto pripade A, ak zo start do samohl prejde na pismeno E, tak vypise E
hviezda namiesto stavu do kt. prejst: neprechadza sa do ineho stavu, ostava sa v rovnakom, t.j.
START: AEIOUY : START : A <=> START: AEIOUY : * : A
resp: S1, S2, S3: 0 : * : 0 znamena ze ked som v S1, dostanem 0 na vstupe tak predjdem znova do S1

pri spracovavani pouzijem 1. pravidlo ktore sa chyti.... , * moze byt aj namiesto startovneho stavu, napr. *: 1:konec:1 - proste ak dostanem 1 na vstupe tak koncim bez ohladu na stav
* na mieste vstupu (e.g. S1:*:koniec:X) tak proste akekolvek pismeno zo vstupui to vezme

- ak sa nechyti ziadne pravidlo, hodi error

- vstup zo suboru, organizovany po riadkoch, v subore su iba pravidla tvaru "stavy: vstupy: ciel. stav: vystup"
- pociatocny stav je na 1. riadku vo vst. subore, t.j.
START
pravidla (st: vst: cs: out)

priklad automatu:
start
start : AEUIOY : * : A
* : BCD...Z(proste rucne vypisane pismena bez samohl) : start : O
* : * : * : * //nic sa nemeni, proste vstup sa kopiruje na vystup
- pouzije sa vzdy 1. pravidlo ktore sa chyti...

lepsi priklad automatu: - na vystup same 0 a ak su dva samohl za sebou tak 1
start
start : AEIOUY : samohlaska : 0
start : * : * : 0
samohlaska : AEIOUY : * : 1
samohlaska : * : start : 0

moj navrh: stavy si budem drzat v nejakom zozname, najprv. prejdem vstup a budem mat zoznam: stav, pismena na kt. chyta, stav kam ma ist, vystup
mozno urobit aj tak ze vzdy za kazdym pismenom budem prechadzat znova vstupny subor a hladat pravidlo...
(odporuca sa robit cez STL a samo classy atd.)

pouzitim hviezdiciek mozem robit viacero roznych popisov toho isteho automatu...

ak blby tvar riadku -> chyba

vstup pisem asi cez cin alebo ako, proste repeat citaj znak, spracuj, vyplujznak a znova

Tak a moje riesenie:

#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;

class pravidlo {

public:
string pocST; //zoznam stavov z kt. idem
string vstup; //vstup na kt. pojdem dalej
string cielST; //kam pojdem dalej - pozor, tento musi byt prave jeden stav
string vystup; //pismeno ktore mam vypisat
}; //pravidlo

void main() {
vector<pravidlo> PR;
string START; //pociatocny stav
string ACTUAL;
ifstream vstup("pravidla2.txt");

if ((getline(vstup, START) )==0) {throw "chybne pravidla: start";}
ACTUAL=START;
//cout << ACTUAL << endl;
string line;
string pST;
string vst;
string cST;
string vys;
pravidlo P;
while (getline(vstup, line)) {
pST="";vst="";cST="";vys="";
int a=0, La=0;
a=line.find(":",0);
pST=line.substr(La, a-La);
La=a+1;
a=line.find(":",La);
vst=line.substr(La, a-La);
La=a+1;
a=line.find(":",La);
cST=line.substr(La, a-La);
La=a+1;
a=line.find(":",La);
vys=line.substr(La, a-La);
P.cielST=cST;
P.pocST=pST;
P.vstup=vst;
P.vystup=vys;
//skontrolujem line ci ma spravny format
PR.push_back(P);
}; //while
/*
for (vector<pravidlo>::iterator w = PR.begin(); w!=PR.end(); w++) {
cout << w->pocST << ":" << w->vstup << ":" << w->cielST << ":" << w->vystup << endl;
}
*/

char VST;
int nasiel=0;
string tmp;
string tmp2;
while (true){ //ukoncovaci znak bude . (bodka)
cin >> VST;
if (VST=='.') {break;}
for (vector<pravidlo>::iterator w = PR.begin(); w!=PR.end(); w++) {
tmp=w->pocST;
if ((tmp.find(ACTUAL)!=-1) || (tmp=="*")) { //nasiel som aktualny stav medzi pociatocnymi
tmp=w->vstup;
if ( (tmp.find(VST)!=-1 ) || (tmp=="*") ) { //nasiel som pismeno medzi vstupnymi - > vystup & zmena stavu
nasiel=1;
tmp2=w->vystup;
if (tmp2=="*") {tmp2=VST;}
cout << tmp2;
tmp=w->cielST;
if ((tmp=="*")) {tmp=ACTUAL;};
ACTUAL = tmp;
}//if vst
}// if actual
if (nasiel) break; //po prvom najdenom pravidle koncim
}//for
if (nasiel==0) {cout << "nenasiel som stav z ktoreho mam pokracovat!" << endl;}
nasiel=0;
};//while

/*
for (vector<pravidlo>::iterator w = PR.begin(); w!=PR.end(); w++) {
cout << w->pocST << ":" << w->vstup << ":" << w->cielST << ":" << w->vystup << endl;
}
*/


cout << endl << "koniec programu" << endl;
};

Tak a este EDIT:
vsetky zapoctaky co doteraz boli a niekto ich niekde zverejnil, tak som ich vsetky dal do lotshare/OOP, su tam aj vzorove riesenia cviceni p. Hnetynku, v adresari domace su vypracovane priklady, vzdy na zaciatku programu je v komentaroch zadanie - je to skratka to vsetko co som kde kade tade pozbieral tuna na forach. Tak dufam ze to aspon niekomu pomoze.
Návštěvník

Příspěvek od Návštěvník »

co je toto za kravinu? sedim nad tym 15 minut a nechapem...
Uživatelský avatar
Dawe
Supermatfyz(ák|ačka)
Příspěvky: 360
Registrován: 12. 10. 2004 12:32
Typ studia: Informatika Mgr.
Bydliště: Doma a nebo na koleji

Příspěvek od Dawe »

Nejsi jediny...
THX
Matfyz(ák|ačka) level I
Příspěvky: 8
Registrován: 7. 2. 2006 12:44
Typ studia: Informatika Bc.
Kontaktovat uživatele:

Příspěvek od THX »

Treba urobit simulator jednostavoveho automatu. Automat precita znak, zmeni stav, vypise znak.
Vstup je - nazov startovneho stavu a pravidla (tieto pravidla popisuju dany automat, ak chcete mozete si ich prekreslit na graf).
popis pravidla je nasledovny:
aktualny stav:pismeno na vstupe:cielovy stav:vystup

Aktualny stav je meno stavu v ktorom sa momentalne automat nachadza, pismeno na vstupe je nejaky string obsahujuci pismena. Ak sme v stave ktory sa zhoduje so stavom pravidla a na vstupe je pismeno zo vstupnych pre dany stav, tak prejde automat do cieloveho stavu a vypise vystup (ktory je jedno pismeno).

Namiesto nazvou stavov a vst/vyst pismen mozu byt aj *;
* znamena vzdy aktualny stav/aktualne pismeno.
Odpovědět

Zpět na „2005“