資源簡介
用C語言實現NFA到DFA的轉換過程
NFA (nondeterministic finite-state automata)是不確定性有限狀態自動機的簡寫,NFA的定義為:
一個不確定性有限狀態自動機由以下部分所組成:
A. 一個有限的輸入字符集I
B. 一個有限的狀態集S
C. 狀態轉換函數f: S x I -> P(S),P(S)為s的冪集
D. 一個結束狀態集Q,Q是S的子集
E. 一個初始狀態s0 (屬于S)
F. 表示為A(I, S, f, Q, s0)
與NFA相對應,DFA (deterministic finite-state automata)表示確定性有限狀態自動機。與NFA不同,DFA不存在Epsilon轉換,并且每一個狀態轉換函數的值只對應一個狀態,即一個狀態輸入一個字符,只能有一個狀態相對應。
NFA與DFA的區別
顯然,DFA更加適合我們進行字符串匹配,因為輸入一個字符,總能從一個狀態確定地轉換為另一個狀態,直到終結狀態。NFA一個輸入可能對應多個狀態,因此需要進行回溯,先嘗試一條路徑,發現走不通,再回退到原來的狀態嘗試另外一條路徑,顯然匹配算法不如DFA簡單。
給定一個NFA,總有一個DFA與之對應,即一個NFA可以轉換成一個等價的DFA,我們將使用子集構造算法實現NFA到DFA的轉換。

代碼片段和文件信息
#include?
#include?
#include?
#define?MAX?10
#define?INFINIT?32767
#define?NumMaxChar?10
#define?NumMAXTN?10?
///////////////////////////////數據結構定義//////////////////////////////////?
//////////////////////////NFA圖結構//////////////////////////////////
typedef?struct?edge
{//邊
int?dest;
char?cost;
struct?edge?*link; //指向下一邊
}*Edge;?
typedef?struct?vertex
{//頂點
char?data; //狀態
Edge?adj; //邊
}*Vertex;?
typedef?struct?graph
{//圖
Vertex?NodeTable;
int?NumVertex;
int?MaxNumVertex;
int?NumEdge;
}*Graph;
//////////////////////////////////////////////////////////////////////
//////////////////////////狀態轉換表機構//////////////////////////////
typedef?struct?tablenode
{//轉換表節點
char?newname;//新命名
char?ch[MAX];//頂點集合
}*TableNode;?
typedef?struct?tablequeue
{//轉換表列
TableNode?TN[MAX];//轉換表節點數組
char?transword;//轉換條件
int?NumTn;//添加的頂點數
}*TableQueue;?
typedef?struct?transmatrix
{//狀態轉換矩陣
TableQueue?TQ;//轉換表列組
int?transnum;//轉換表列數
}*TranMatrix;?
/////////////////////////////////////////////////////////////////////////////?
///////////////////////////////////圖操作////////////////////////////////////??
int?GraphEmpty(Graph?g)
{//圖判空
return?g->NumVertex==0;
}?
int?GraphFull(Graph?g)
{//判圖滿
return?g->NumVertex==g->MaxNumVertex;
}?
char?GetValue(Graph?gint?i)
{//尋找下標為i的頂點
return?(i>0?&&?iNumVertex??g->NodeTable[i].data:‘?‘);
}
??
void?Insert_Vertex(Graph?gchar?vertex)
{//插入新的頂點
g->NodeTable[g->NumVertex].data=vertex;
g->NodeTable[g->NumVertex].adj=NULL;
g->NumVertex++;
}?
void?Insert_Edge(Graph?gint?v1int?v2char?weight)
{//插入邊
Edge?p;
p=(Edge)malloc(sizeof(struct?edge));
p->cost=weight;
p->dest=v2;
p->link=g->NodeTable[v1].adj;
g->NodeTable[v1].adj=p;?
}?
int?GetVertexPos(Graph?gchar?v)
{//得到頂點在圖中的下標
int?i=0;
while(iNumVertex)
{
if(g->NodeTable[i].data==v)
return?i;
i++;
}
return?INFINIT;
}?
void?Construct_Graph(Graph?g)
{//創建圖
int?kjivexnedgen;
char?headtailname;
char?weight;
g->NumVertex=0;
g->NumEdge=0;
g->MaxNumVertex=MAX;
g->NodeTable=(Vertex)malloc((g->MaxNumVertex)*sizeof(struct?vertex));
printf(“輸入NFA狀態數:“);
scanf(“%d“&vexn);
printf(“輸入NFA狀態名稱:\n“);
flushall();
//依次獲取狀態名稱,并將這些頂點插入圖中
for(i=0;i {??
scanf(“%c“&name);
flushall();
Insert_Vertex(gname);
}
????printf(“輸入NFA的邊數:“);
????scanf(“%d“&edgen);
????printf(“輸入?起始狀態,接受字符?和?到達狀態:\n“);
????flushall();
//依次獲取邊的信息(起始頂點,接受字符,到達的頂點),并將這些邊插入圖中
for(i=0;i {???
flushall();
scanf(“%c?%c?%c“&tail&weight&head);
k=GetVertexPos(gtail);
j=GetVertexPos(ghead);
Insert_Edge(gkjweight);
}
}?
void?Destruct_Graph(Graph?g)
{//銷毀圖??
int?i;
Edge?p;
for(i=0;iNumVertex;i++)
{
p=g->NodeTable[i].adj;
while(p!=NULL)
{
g->NodeTable[i].adj=p->link;
p->link=NULL;
free?(p);
p=g->NodeTable[i].adj;
}
}
g->N
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件???????9191??2008-11-27?20:02??aa.cpp
-----------?---------??----------?-----??----
?????????????????9191????????????????????1
- 上一篇:動態分區分配方式,C語言實現的
- 下一篇:AES 128位加解密C++源碼(加鹽)
評論
共有 條評論