背景
通常使用有向图来描述NFA。每个边和顶点都标记为0或1,表示可能的过渡。顶点表示NFA的状态。标记为0的是不接受状态,标记为1的是接受状态。
- 它采用有限长度的输入字符串。通常,输入字符串是0和1的二进制序列。
- 我们从始终是开始状态的顶点1开始,然后按照输入字符串的位顺序给出的边沿进行操作,直到输入字符串没有其他位为止。
- 术语“非确定性”是指在任何状态V下,我们都有不止一种选择跟随边缘。 NFA消耗输入字符串,状态集Q代表NFA可能的移动。
- 如果Q包含至少一个最后一个顶点正在接受的状态,则我们说NFA接受了输入字符串,否则NFA拒绝了输入字符串。
- 每个NFA都不是DFA,但是每个NFA都可以转换为DFA。
NFA的示例:
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基础课程》。