среда, 19 января 2011 г.

Устранение недостижимых состояний любого конечного автомата

Написать программу, реализующую устранение недостижимых состояний любого конечного автомата (предусмотреть введение произвольного множества нетерминалов, входных символов, начального и конечного состояний и правил перехода. Правила перехода можно хранить в двумерном массиве).

Рассмотрим алгоритм устранения недостижимых состояний. Алгоритм состоит в следующем.
Вход: КА .
Выход: КА без недостижимых состояний.
1. Поместить начальное состояние КА в список достижимых состояний.
2. Для новых элементов списка достижимых состояний пополнить список группой их состояний-преемников, отсутствующих в списке.
3. Повторять п.2, пока список достижимых состояний не перестанет меняться.
4. Исключить из множества состояний КА все состояния, отсутствующие в списке достижимых состояний.
5. Исключить недостижимые заключительные состояния и функции переходов, содержащие недостижимые состояния.
Программная реализация на языке C++

#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;

int main(int argc, char *argv[])
{
    fstream read,write;//поток для чтения/записи из файла
    read.open("avtomat.txt",ios::in);//открываем файл avtomat.txt
    write.open("avtomat_.txt",ios::out);//открываем файл avtomat_.txt
    if(!read||!write){cout<<"File read Error!"<<endl;system("PAUSE");return EXIT_SUCCESS;};//если возникла ошибка при чтении
    char sostoanie[128],start,end[128],dost[128],nedost[128]={}; //sostoanie-состояния,start - начальное состояние, end - конечные состояния, stroka - строка для распознавания//dost - достижимые состояния
    int razmer,c=1,flag; //razmer - количество правил
    read.getline(sostoanie,128,'\n');cout<<sostoanie<<endl;//считали множество состояний
    read>>start;read.get();cout<<"Start "<<start<<endl;
    read.getline(end,128,'\n');cout<<"Finish "<<end<<endl;//считали конечные состояния
    read>>razmer;read.get(); //считали количество правил
    char pravila[3][razmer],temp[4];//pravila массив с правилами, temp промежуточный массив для чтения правил
    dost[0]=start;//начальное состояние всегда достижимо *1 ШАГ АЛГОРИТМА*
    for(int i=0;i<razmer;i++)//считываем правила
    {
           read.getline(temp,4,'\n');cout<<temp<<endl;
           for(int j=0;j<3;j++)
                   pravila[j][i]=temp[j];               
    };
    //ищем достижимые состояния
    for(int i=0;i<strlen(sostoanie);i++)
    {
       for(int k=0;k<razmer;k++)            
          if(sostoanie[i]==pravila[2][k]&&pravila[0][k]!=pravila[2][k]&&sostoanie[i]!=start)
             {
                dost[c]=sostoanie[i];c++;break;
              }
   }
   //находим недостижимые состояния
   c=0;
   for(int i=0;i<strlen(sostoanie);i++)
   {
           flag=0;
   for(int k=0;k<strlen(dost);k++)            
          if(sostoanie[i]!=dost[k])
             {
               flag++;
              } 
           if(flag==strlen(dost))
           {
             nedost[c]=sostoanie[i];c++; 
           }       
  }
  cout<<endl<<"=========="<<endl<<"Nedostigimue sostoania "<<nedost<<endl<<"=========="<<endl;
  write<<dost<<endl<<start<<endl;//записываем в новый файл новые состояния и начальное состояние
  cout<<dost<<endl<<"Start "<<start<<endl;
  for(int i=0;i<strlen(end);i++)//исключаем из конечных состояний недостижимые
  for(int j=0;j<strlen(nedost);j++)
  if(end[i]!=nedost[j])
  {
     cout<<"Finish "<<end[i]<<endl;
     write<<end[i];//записываем конечные состояния в новый файл
  }
  for(int i=0;i<razmer;i++)//исключаем из правил правила с недостижимыми состояниями
  for(int j=0;j<strlen(nedost);j++)
  if(pravila[0][i]!=nedost[j]&&pravila[2][i]!=nedost[j])
  {
     cout<<pravila[0][i]<<pravila[1][i]<<pravila[2][i]<<endl;
     write<<endl<<pravila[0][i]<<pravila[1][i]<<pravila[2][i];//записываем новые правила в файл
  }
  system("PAUSE");return EXIT_SUCCESS;
}

1 коммент.:

Unknown комментирует...

А как должен выглядеть исходный файл?

Отправить комментарий