Diskuze: pomoc s implementaci konečneho automatu v jazyce C
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.
MrPabloz:22.11.2015 21:29
Tak tu pošli, jak ten tvůj automat vypadá. Jako nakreslené stavy a přechody pro jaké znaky. Nebo nevíš ani to?
David Novák:22.11.2015 21:32
A co konkrétně ti nefunguje..? Ve škole vám to nevysvětlili?
Tomas:22.11.2015 21:37
No ja ani nevim jestli jsem ho nakreslil zpravně a myslim ze je to ten
modrej nebo zelenej a poslu sem este jak jsem to napsal
A díky moc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char a, b, c;
int stav = 0;
char volba;
printf("cekam na zadani\n");
while (true) // problem s podminkou
{
scanf("%c", &volba);
switch (stav)
{
case 0: //zacatek
if(volba == 'a')
{ printf("zustavate v pocatecnim stavu ktery neni konecny");
stav = 0;}
else if(volba == 'b')
{
stav = 1;
}
else if(volba == 'c'){
stav=2;
}
break;
case 1: // nejak to poresit aby i kdyz prijde b tak to slo do erroru
if(volba == 'a') {
stav = 5;
}
else if(volba == 'c','b'){
stav =6;
}
break;
case 2: //stav c1 napsat sem nejaky cyklus by nebylo spatne
printf("ste ve stavu c1 ktery neni konecny");
if(volba == 'c')
{
stav = 3;}
else if(volba == 'a'){
stav = 2;
} else if(volba == 'b'){
stav = 1;
}
break;
case 3: // stav c2
printf("ste ve stavu c2 ktery neni konecny");
if(volba == 'a')
{
stav = 3;
}else if(volba == 'b')
{
stav = 1;
}
else if(volba == 'c'){
stav = 4;
}
break;
case 4: //ctav c3
printf("ste ve stavu c3 ktery neni konecny");
if(volba == 'a'){
stav = 4;
}else if(volba == 'b'){
stav = 1;
}
else if(volba == 'c'){
stav = 6;
}
break;
case 5: //stav a
printf("zustavate ve stavu a ktery je konecny");
if(volba == 'a'){
stav = 5;}
else if(volba == 'b'){
stav =1;
} else if(volba == 'c'){
stav = 2;
}
break;
case 6: //stav error
printf("error");
}}
}
Tomas:22.11.2015 21:42
Tu implementaci nam nikdo nevysvětlil, a já jsem začal programovat v říjnu tohoto roku, takže vtom nejsem eště tak zběhlý.... bohužel...
MrPabloz:22.11.2015 21:50
No nevím, nějak se v tom nákresu nevyznám (toho automatu), nechceš to
překreslit lépe, protože takhle mi to příjde že to máš špatně skus tam jasně zadat startovní
stav (míří do něj z nikde šipka) a pak konečný stav (dvojitý kruh).
Poté ke každé šipce jasně napsat jaký znak, protože u toho zeleneho mi to
příjde že z c1 de na c2 znakem b, i když to tak není asi myšleno
Ohledně kodu, každý stav si představ jako jednu funkci. ta poté volá
další podle vstupu. takže např.
void stav1()
{
char z = ctiDalsiZnak();
if(z == 'a')
stav2();
else if(z == 'b')
stav3();
else if(z == 'c')
stav4();
else
stavError();
}
a tak to bude podobné všude
Tomas:22.11.2015 22:29
za chvíly to pošlu a ja nevim jestli je zpravně.... a to co jsi napsal mam napsat do toho svyho kodu?
David Novák:23.11.2015 0:23
Takhle určitě není dobré v C realizovat konečný automat..
To, co má Tomas je správný postup - case v cyklu načítání znaků a obsluha jednotlivých stavů.. Akorát bych doporučil udělat si enum se stavy pro lepší přehlednost
Nemám čas se koukat na tvé zadání, ale pro inspiraci se můžeš podívat na jednoduchý automat, co jsem zde zveřejnil já před nějakou dobou: http://www.itnetwork.cz/…linux-delcom
Libor Šimo (libcosenior):23.11.2015 7:37
Našiel som niečo jednoduchšie na pochopenie:
http://www.matematika.cz/konecny-automat
Tomas:23.11.2015 9:47
děkuju moc, ale popravdě už o tom članku vím, hodně jsem se jím inspiroval..... akorát ten muj automat ma ukazovat jenom stav ve kterym konci, (ale ukazuje všechny kterjma prochází) a potom kdyz zadáme sekvenci třeba cbacbacbac tak tam mam 4 c a stejně mi to nejde do erroru.... tak moc nevim co stim mam dělat, a eště jak tam zakomponovat aby se program vypnul když přijde jiný znak....
Tomas:23.11.2015 9:51
děkuju moc, ale není tam jak se to ma implementovat do cecka.... a můžete se mi někdo prosím podívat i na ten automat prosím, když budete mít naladu jestli ho mám dobře? děkuji moc...
Tomas:23.11.2015 9:54
A taky nevím co je to ,,enum,, promiň za mojí nezkušenost ale jsem fakt začátečník...
Libor Šimo (libcosenior):23.11.2015 13:50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[128];
int stav;
char c, pokracovat;
int i, j, pom_b, pom_c, velkost;
for (;;) {
stav = 0;
pom_b = 0;
pom_c = 0;
printf("Zadajte slovo na kontrolu: ");
fflush(stdin);
scanf("%s", buffer);
velkost = strlen(buffer);
for (i = 0; i < velkost; i++) {
c = buffer[i];
switch(stav) {
case 0:
if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
case 1: // a
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (c == 'c') {
pom_c++;
stav = 3;
}
break;
case 2: // b
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'b' || buffer[i] == 'c')
stav = 5;
else if (buffer[i] == 'a')
stav = 1;
break;
case 3: // c
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 2) {
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
}
}
if (stav == 4)
printf("\nSlovo preslo, b = %d, c = %d, tav = %d\n", pom_b, pom_c, stav);
else
printf("\nSlovo nepreslo, b = %d, c = %d, stav = %d\n", pom_b, pom_c, stav);
printf("\nPre nove zadanie stlacte y: ");
fflush(stdin);
pokracovat = getch();
if (pokracovat == 'y') {
system("cls");
}
else {
putchar('\n');
break;
}
}
return 0;
}
Tomas:23.11.2015 15:07
Dekuju moc a k cemu je ten prikaz flush(stdin);? A poslu jsem ten Tvuj program kterej sem trochu upravil aby vic vyhovoval zadani a prosím kam ma dopsat ze kdyz prijde jiny znak nez a,b,c tak se program ukonci... diky moc
Libor Šimo (libcosenior):23.11.2015 15:33
Vyprázdni buffer, aby ti tam neostal visieť znak '\n' - teda enter.
"kdyz prijde jiny znak nez a,b,c" to zvládneš aj sám. Všade sú tam len
podmienky.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[128];
int stav;
char c;
int i, j, pom_b, pom_c, velkost;
printf("Zadajte slovo na kontrolu: ");
for (;;) {
stav = 0;
pom_b = 0;
pom_c = 0;
fflush(stdin);
scanf("%s", buffer);
velkost = strlen(buffer);
for (i = 0; i < velkost; i++) {
c = buffer[i];
switch(stav) {
case 0:
if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
case 1: // a
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (c == 'c') {
pom_c++;
stav = 3;
}
break;
case 2: // b
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'b' || buffer[i] == 'c')
stav = 5;
else if (buffer[i] == 'a')
stav = 1;
break;
case 3: // c
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 2) {
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
}
}
if (stav == 4)
printf("\jste ve stavu, %d\n ktery je konecny", stav);
else if(stav==5){printf("error");}
else
printf("\njste ve stavu, stav = %d\n ktery neni konecny", stav);
fflush(stdin);
}
return 0;
}
Akorat este nevim jak to udelat, ze kdyz mi prijdou 3 c aby to slo do erroru diky moc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char buffer[128];
int stav;
char c;
int i, j, pom_b, pom_c, velkost;
printf("Zadajte slovo na kontrolu: ");
for (;;) {
stav = 0;
pom_b = 0;
pom_c = 0;
fflush(stdin);
scanf("%s", buffer);
velkost = strlen(buffer);
for (i = 0; i < velkost; i++) {
c = buffer[i];
switch(stav) {
case 0:
if (buffer[i] == 'a')
stav = 0;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
case 1: // a
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'a')
stav = 1;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (c == 'c') {
pom_c++;
stav = 3;
}
break;
case 2: // b
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 1) {
stav = 4;
}
else if (buffer[i] == 'b' || buffer[i] == 'c')
stav = 5;
break;
case 3: // c
if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'a' && i == velkost - 2) {
stav = 4;
}
else if (pom_b >= 1 && pom_c <= 3 && buffer[i] == 'c' && i == velkost - 2) {
pom_c++;
stav = 4;
}
else if (buffer[i] == 'a')
stav = 3;
else if (buffer[i] == 'b') {
pom_b++;
stav = 2;
}
else if (buffer[i] == 'c') {
pom_c++;
stav = 3;
}
break;
}
if(pom_c>3){stav=5;}
}
if (stav == 4)
printf("\jste ve stavu, %d\n ktery je konecny", stav);
else if(stav==5){printf("error");}
else
printf("\njste ve stavu %d\n ktery neni konecny", stav);
fflush(stdin);
}
return 0;
}
Ze ten stav 1 myslim ze je zbytecny v tom co jsem upravil jako posledni a to je tenhle
Libor Šimo (libcosenior):23.11.2015 17:31
Robil som to popri svojej práci, teraz to už je na tebe. Uprav si to, ako
potrebuješ.
Najlepší spôsob je nechať si vypisovať čo sa priebežne deje.
Napríklad:
vypisoval by som výsledky po každom písmene. To ti môže ukázať cestu, ako
to upraviť.
V každom case by som pre break; dal asi toto:
printf("znak = %c, b = %d, c = %c, stav = %d\n", buffer[i], pom_b, pom_c, stav);
Vyskúšaj to.
Tomas:23.11.2015 17:36
Me to prijde taky lepsi, ale nas ucitel je hodne pedant na to aby to vypadalo jako v zadani.... a kam ma dat tu podminku, aby to prijimalo jenom znaky abc? a kdyz budou jiny tak se ukonci program... ja totis ani nevim jaky je prikaz k ukonceni programu...
Zobrazeno 25 zpráv z 25.