Неправильная работа распознавателя единиц

stut
Дата: 09.04.2015 04:41:00
Вот у меня есть созданный код для выявление в введеной строке консоле
трех единиц. Если ввожу сразу 111 то получаю ответ что строка правльная, если иначе --0111, -1011 --что неправильная, хотя это уведомления должно было появляться лиш при например 00011
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

void razposnavatel() {
	char k[10];
	cout << "VVesti stroku 0 i 1:";
	cin >> k;
	int state = 0;
	for (int i = 0; k[i] != '0'; i++) {
		switch (state) {
		case 0: {
			if (k[i] == '0') {
				state = 0;
				break;
			};
			if (k[i] == '1') {
				state = 1;
				break;
			};
			break;
		}
		case 1: {
			if (k[i] == '0') {
				state = 1;
				break;
			};
			if (k[i] == '1') {
				state = 2;
				break;
			};
			break;
		}
		case 2: {
			if (k[i] == '0') {
				state = 2;
				break;
			};
			if (k[i] == '1') {
				state = 3;
				break;
			};
			break;
		}
		case 3: {
			if (k[i] == '0') {
				state = 3;
				break;
			};
			if (k[i] == '1') {
				state = 4;
				break;
			};
			break;
		}
		}
	}
	if (state == 3)
		cout << "pravylno";
	else
		cout << "netu v stroke 3 edinicy";
	cout << state;

}

int main() {
	razposnavatel();
	return 0;
}
stut
Дата: 09.04.2015 04:46:33
stut,
То есть если в начале есть 0 то
cout<<state; выводит что состояние 0 --= хотя потом могут идти 1 которые при состояние 0 увеличивают его на 1.
Если 10111 -- то состояние 1?
SashaMercury
Дата: 09.04.2015 06:37:19
stut, да вы шутите. Пройдитесь циклом по массиву, и в счётчик просуммируйте количество единиц.



for(...){
   if(...){
        ++count;
   }
}



PS
Ваш код выше полностью некорректен.
SashaMercury
Дата: 09.04.2015 06:39:30
подробнее на всякий случай.
SS
stut, да вы шутите. Пройдитесь циклом по массиву, и в счётчик просуммируйте количество единиц.



count==0;
for(int i=0;i<len;++i){
   if(a[i]=='1'){
        ++count;
   }
}


Dima T
Дата: 09.04.2015 06:48:27
Ищи ошибку в этой строчке.
stut
for (int i=0; k[i]!='0'; i++) {

Как написал - так и работает.
stut
Дата: 09.04.2015 11:45:42
Хорошие у вас подсказки о сумирование.
for (int i=0; k[i]!='0'; i++) ---> for (int i=0; k[i]!='\0'; i++) -- вот спасибо очень -- а то бы еще долго искал.
У меня еще другой пример уже не к конечным автоматам, а к МП-автоматам с магазинной памяттью. У них должен быть магазин (где нули заставляют стек увеличиватся на 1, а 1--выталкивают некий условный символ Z. D начале есть еще в стеке символ пустого пространства-p.)/ Мне надо следующий код записать с помошью стека.
надо распознавателем проверить строку: {In0n |n=5} + {Im0m |n=4} n--верхний индекс -- я так понимаю мне надо найти такую строку в входных цепях:
1111100000|00001111 или если между двумя подмножествами может быть иная упорядоченость символов то например 1111100000|0001|00001111.
Это я делаю с помошью кода такого как предыдущий а надо с помощью стека. Не подскажите как это делать. Я так понимаю--состояние1--вход 1 (занесение в стек), 2-потом вход 0 выталикание со стека. Потом надо наверное изменить ход работы стека на занесение Z
при встече 0 в {Im0m |n=4}, а потом выталкивание при встрече 1.
Вот код который подходит под ка, а не мп-автомат.

+
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

int state = 0;

void razpoznavat() {
	char k[20];
	cout << "Vvesti stroku 0 i 1:";
	cin >> k;
	for (int i = 0; k[i] != '\0'; i++) {

		switch (state) {
		case 0: {
			if (k[i] == '0') {
				state = 20;
				break;
			};
			if (k[i] == '1') {
				state = 1;
				break;
			};
			break;
		}

		case 1: {
			if (k[i] == '0') {
				state = 20;
				break;
			};
			if (k[i] == '1') {
				state = 2;
				break;
			};
			break;
		}

		case 2: {
			if (k[i] == '0') {
				state = 20;
				break;
			};
			if (k[i] == '1') {
				state = 3;
				break;
			};
			break;
		}

		case 3: {
			if (k[i] == '0') {
				state = 20;
				break;
			};
			if (k[i] == '1') {
				state = 4;
				break;
			};
			break;
		}

		case 4: {
			if (k[i] == '0') {
				state = 20;
				break;
			};
			if (k[i] == '1') {
				state = 5;
				break;
			};
			break;

			case 5:
			{
				if (k[i] == '0') {
					state = 6;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 6:
			{
				if (k[i] == '0') {
					state = 7;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 7:
			{
				if (k[i] == '0') {
					state = 8;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 8:
			{
				if (k[i] == '0') {
					state = 9;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 9:
			{
				if (k[i] == '0') {
					state = 10;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 10:
			{
				if (k[i] == '0') {
					state = 11;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 11:
			{
				if (k[i] == '0') {
					state = 12;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 12:
			{
				if (k[i] == '0') {
					state = 13;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 13:
			{
				if (k[i] == '0') {
					state = 14;
					break;
				};
				if (k[i] == '1') {
					state = 20;
					break;
				};
				break;
			}

			case 14:
			{
				if (k[i] == '0') {
					state = 20;
					break;
				};
				if (k[i] == '1') {
					state = 15;
					break;
				};
				break;
			}

			case 15:
			{
				if (k[i] == '0') {
					state = 20;
					break;
				};
				if (k[i] == '1') {
					state = 16;
					break;
				};
				break;
			}

			case 16:
			{
				if (k[i] == '0') {
					state = 20;
					break;
				};
				if (k[i] == '1') {
					state = 17;
					break;
				};
				break;
			}

			case 17:
			{
				if (k[i] == '0') {
					state = 20;
					break;
				};
				if (k[i] == '1') {
					state = 18;
					break;
				};
				break;

			}
		}
		}
	}
}


int main()
{
	razpoznavat()
	if (state == 18)
		cout << " Pravilnaya cep ";
	else
		cout << "Nepravilnaya cep";
	cout << state;
	return 0;
}
Dima T
Дата: 09.04.2015 12:30:38
stut
У меня еще другой пример уже не к конечным автоматам, а к МП-автоматам с магазинной памяттью. У них должен быть магазин (где нули заставляют стек увеличиватся на 1, а 1--выталкивают некий условный символ Z. D начале есть еще в стеке символ пустого пространства-p.)/ Мне надо следующий код записать с помошью стека.
надо распознавателем проверить строку: {In0n |n=5} + {Im0m |n=4} n--верхний индекс -- я так понимаю мне надо найти такую строку в входных цепях:
1111100000|00001111 или если между двумя подмножествами может быть иная упорядоченость символов то например 1111100000|0001|00001111.
Это я делаю с помошью кода такого как предыдущий а надо с помощью стека. Не подскажите как это делать. Я так понимаю--состояние1--вход 1 (занесение в стек), 2-потом вход 0 выталикание со стека. Потом надо наверное изменить ход работы стека на занесение Z
при встече 0 в {Im0m |n=4}, а потом выталкивание при встрече 1.

Ничего не понял. Какой-то поток сознания. Объясни на простом примере чего делаешь.
MasterZiv
Дата: 09.04.2015 14:39:22
Dima T
Ничего не понял. Какой-то поток сознания. Объясни на простом примере чего делаешь.


Да лабы человек делает...
mayton
Дата: 09.04.2015 16:49:54
Интерес бы представлял генератор который такие автоматы создаёт. Но копать
рукотворный код весьма уныло. Он слишком плоский чтобы представлять интерес
для изучения, но и слишком объёмный (этакую "простыню" только под спойлер) чтобы
рассматривать его как учебное пособие.
stut
Дата: 09.04.2015 22:42:06
Дан МП-автомат точнее строка которую он распознает.
{In0n |n=5} + {Im0m |n=4}. Знаю что первый или второй компонент занчит что после ен или ем 0 (1) идет столько же другой двоечной цыфри. А что значит сумирование точно не знаю. Хотя вполне логичное предположение я сделал.
Потом есть код который рапознает эти строчки:
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int state=0;
void rozpiznavach () {
char k[20];
cout<<"Vvedit ryadok 0 i 1:";
cin >>k;
for (int i=0; k[i]!='\0'; i++) {

switch (state) {
case 0: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=1; break;};
break;
}

case 1: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=2; break;};
break;
}

case 2: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=3; break;};
break;
}


case 3: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=4; break;};
break;
}

case 4: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=5; break;};
break;

case 5: {
if (k[i]=='0') {state=6; break;};
if (k[i]=='1') {state=20; break;};
break;
}

case 6: {
if (k[i]=='0') {state=7; break;};
if (k[i]=='1') {state=20; break;};
break;
}



case 7: {
if (k[i]=='0') {state=8; break;};
if (k[i]=='1') {state=20; break;};
break;
}

case 8: {
if (k[i]=='0') {state=9; break;};
if (k[i]=='1') {state=20; break;};
break;
}



case 9: {
if (k[i]=='0') {state=10; break;};
if (k[i]=='1') {state=20; break;};
break;
}

case 10: {
if (k[i]=='0') {state=11; break;};
if (k[i]=='1') {state=20; break;};
break;
}


case 11: {
if (k[i]=='0') {state=12; break;};
if (k[i]=='1') {state=20; break;};
break;
}


case 12: {
if (k[i]=='0') {state=13; break;};
if (k[i]=='1') {state=20; break;};
break;
}


case 13: {
if (k[i]=='0') {state=14; break;};
if (k[i]=='1') {state=20; break;};
break;
}

case 14: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=15; break;};
break;
}

case 15: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=16; break;};
break;
}


case 16: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=17; break;};
break;
}

case 17: {
if (k[i]=='0') {state=20; break;};
if (k[i]=='1') {state=18; break;};
break;

}
}
}
}
}
int main()

{
rozpiznavach ();
if (state==18) cout<<"ryadok pravylnyy";
else cout<<"ryadok ne mistyt 3-yoh odynyc";
return 0;
}
--но это только один вариант. Вообще МП-автомат работает со стеком. Сперва помещается символ пустого пространства --потом при поступление нулей стек заполняется знаком Z--потом при входе 1. выталкивается.Е если все 1 выталкнуты значит строчка подходит под правило.
{0mIm |n=4} -- а не под {Im0m |n=4}. Думаю схема со {In0n |n=5} --аналогична.
Здесь сумирование этих действий?
Потому и вопрос как сделать со стеком.
stack.push (V) пустое пространтсво.
if (k[i]==1) stack.push (Z);
if (k[i]==0) stack.pop;
if stack.top==V; cout<<число единиц равно число нулей в даной цепочке.
Хотя Если не поставит счетчик после каждого push или pop то наверное
не подсчитает сколько там подоряд было единиц и нулей -- 5 или 10 или 100.
В теории МП-автоматы именно через стек моделируются а что через код невозможно реализовать-- задание такое ж ведь есть.