📜  用来模拟不确定自动机(NFA)的C程序

📅  最后修改于: 2021-05-25 23:59:27             🧑  作者: Mango

背景

通常使用有向图来描述NFA。每个边和顶点都标记为0或1,表示可能的过渡。顶点表示NFA的状态。标记为0的是不接受状态,标记为1的是接受状态。

  • 它采用有限长度的输入字符串。通常,输入字符串是0和1的二进制序列。
  • 我们从始终是开始状态的顶点1开始,然后按照输入字符串的位顺序给出的边沿进行操作,直到输入字符串没有其他位为止。
  • 术语“非确定性”是指在任何状态V下,我们都有不止一种选择跟随边缘。 NFA消耗输入字符串,状态集Q代表NFA可能的移动。
  • 如果Q包含至少一个最后一个顶点正在接受的状态,则我们说NFA接受了输入字符串,否则NFA拒绝了输入字符串。
  • 每个NFA都不是DFA,但是每个NFA都可以转换为DFA。

NFA的示例:

11

Starting state - vertex 1
Accepting states - Vertices with double circles(label 1) // Vertex 4
Non ­accepting states - single circles (label 0). // Vertices 1, 2 and 3.

如何检查是否接受字符串?

输入:1010

  • 在状态1中,我们有两种可能性,要么遵循自循环并保持在状态1,要么遵循标记为1的边沿进入状态3。
{1} 1010 --> {1, 3} 010
  • 在状态3中,没有标记为0的边,因此计算将消失。
  • 在状态1中,我们有两种可能性,要么遵循自循环并保持在状态1,要么遵循标记为0的边沿进入状态2。
{1, 3} 010 --> {1, 2} 10
  • 现在从状态2开始没有标记为1的边。计算将消失。我们有两种可能性:要么跟随自环进入状态1,要么跟随标记为1的边线进入状态3。
{1, 2} 10 --> {1, 3} 0
  • 在状态3中,没有标记为0的边。因此计算将消失。在状态1中,我们有两种可能性:要么跟随自环进入状态1,要么跟随标记为0的边沿进入状态2。

{1, 3} 0 --> {1, 2}
  • 现在,NFA已消耗了输入。它可以处于状态1或2,两者都不接受。因此NFA拒绝了输入1010。

输入:1100

{1} 1100 --> {1, 3} 100 {1, 3} 100 --> {1, 3, 4} 00 {1, 3, 4} 
                  00--> {1, 2, 4} 0 {1, 2, 4} 0--> {1, 2, 4}
  • 现在,NFA已消耗了输入。它可以处于状态1、2或4。状态4是接受状态。因此, NFA接受字符串1100。
  • 我们可以轻松地验证给定的NFA是否接受所有以“ 00”和/或“ 11”作为子字符串的二进制字符串。

模拟非确定性有限自动机(NFA)的C程序

输入格式: NFA的邻接表表示采用以下格式。
给定的示例将表示为
边总数:4
边缘连通性:
1 0 4 0 1 0 2 1 1 1 3
2 0 1 0 4
3 0 1 1 4
4 1 2 0 4 1 4

输出格式: NFA按字典顺序接受的前10个二进制字符串(e表示空字符串):{e,0,1,00,01,10,11,000,…}

给定测试用例的示例输出如下:
00
11
000
001
011
100
110
111

C
#include 
#include 
#include 
#include 
#include 
 
int row = 0;
 
// A structure to represent an adjacency list node
struct node
{
    int data;
    struct node* next;
    char edgetype;
 
}typedef node;
 
// Adds an edge to an adjacency list
node* push(node* first , char edgetype , int data)
{
    node* new_node = (node*)malloc(sizeof(node));
    new_node->edgetype = edgetype;
    new_node->data = data;
    new_node->next = NULL;
    if (first==NULL)
    {
        first = new_node;
        return new_node;
    }
    first->next = push(first->next,edgetype,data);
    return first;
}
 
//Recursive function to check acceptance of input
int nfa(node** graph, int current, char* input,
        int* accept, int start)
{
    if (start==(int)strlen(input))
        return accept[current];
 
    node* temp = graph[current];
    while (temp != NULL)
    {
      if (input[start]==temp->edgetype)
        if (nfa(graph,temp->data,input,accept,start+1==1))
           return 1;
      temp=temp->next;
    }
    return 0;
}
 
//Function to generate binary strings of size n
void generate(char** arr, int size, char *a)
{
    if (size==0)
    {
        strcpy(arr[row], a);
        row++;
        return;
    }
    char b0[20] = {'\0'};
    char b1[20] = {'\0'};
    b0[0] = '0';
    b1[0] = '1';
 
    //Recursively generate the binary string
    generate((char**)arr, size-1, strcat(b0,a)); //Add 0 in front
    generate((char**)arr, size-1, strcat(b1,a)); //Add 1 in front
    return;
 
}
 
// Driver program to test above functions
int main()
{
    int n;
    int i, j;
    scanf("%d", &n); //Number of nodes
    node* graph[n+1]; //Create a graph
 
    for (i=0;i


输入:

4
1 0 4 0 1 0 2 1 1 1 3
2 0 1 0 4
3 0 1 1 4
4 1 2 0 4 1 4

输出:

00
11
000
001
011
100
110
111
0000
0001
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。