NFA識別語言

2022-07-08 03:30:19 字數 2826 閱讀 2430

對於給出的nfa和輸入的字串,判斷字串是否是nfa識別的語言。

輸入有多組資料。每組資料的第一行是兩個整數n(n<=50)和m(m<=27),表示nfa有n個狀態,以及字母表有m-1個字元。nfa的n個狀態用整數0~n-1表示,狀態0為起始狀態。字母表包含小寫英文本母的前m-1個字元。接下來的n行,每行有m個整數集(用''括起)。其中,第i行第1列的整數集表示在狀態i-1時,對應於є(空串)的狀態遷移;第i行第j(j>1)列的整數集,表示nfa在狀態i-1,當輸入符號為第j-1個小寫字母時,遷移到的狀態集。接下來的一行包含若干個整數,代表nfa的接受狀態,這一行以-1結尾。接下來的每一行是乙個待識別的字串,字串的長度在1到50之間且只含有小寫字母。字串"#"代表本組資料結束。n=m=0表示輸入結束。

對於每個待識別的字串,如果能被給出的nfa識別,輸出yes;否則輸出no。

4 3

{}

{} {}

{} {}

{} {} {}

3 -1

aaabb

abbab

abbaaabb

abbb

#0 0

yes

noyes

no

由於是nfa,有兩點情況需要尤其注意:

基於上述分析,在識別的時候我們採用如下步驟(以現在在識別第i個字元為例):

在識別完所有的字元之後,我們還需要進行一次空串的轉移判斷,即識別完第n個字元後再去識別空串,看看還能轉移到哪些狀態。

最後,我們遍歷最後保留下來的可能處於的這些狀態,如果這其中有接收狀態,我們就認為這個字串可以被成功識別。

#include #include #include #include #include #include using namespace std;

int n, m; //f[i][j][k]表示輸入字母i時能從狀態j遷移到狀態k

bool f[28][51][51], end_state[51];

int main()

memset(f, 0, sizeof(f));

memset(end_state, 0, sizeof(end_state));

//下面進行狀態轉移的預處理

string str;

for (int i = 0; i < n; i++) 後面有空格的!

int len = str.length(), num = 0;

bool num_begin = false; //意味著是否開始識別數字

for (int k = 0; k < len; k++)

num = num * 10 + str[k] - '0';

}else }}

}} /*for (int i = 0; i < m; i++)

}}*/

//狀態轉移輸入結束

/*下面開始處理空串,即計算乙個狀態在遇到某乙個字元時先經過若干個空串然後再

輸入這個字元可以到達的狀態集合*/

//下面開始預處理接收狀態

int end;

while (1)

end_state[end] = true;

} //預處理接收狀態結束

//下面開始識別字串,看是否可以識別

while (1)

memset(possible_final_state, 0, sizeof(possible_final_state));

int input_len = input_str.length();

for (int i = 0; i < input_len; i++)

}// 如果沒有查詢過,則加入陣列記錄

if (hasbeentrans == false) }}

//空串處理結束

// 下面開始字元讀入處理,查詢讀入當前字元能到達的狀態

for (int k = 0; k < n; k++)

}if (hasbeenfind == false) }}

}//現在計算出的next_state就是讀入當前字元後可能處於的所有狀態

//我們把它賦值給possible_final_state,進行下一輪迭代

for (int k = 0; k < next_state_num; k++)

possible_final_state_num = next_state_num;

/*for (int l = 0; l < possible_final_state_num; l++)

puts("");*/

//printf("possible_num = %d\n", possible_final_state_num);

next_state_num = 0;

}//現在已經讀入了所有的字元,我們再看看它再讀入空串能到達哪些狀態

for (int j = 0; j < possible_final_state_num; j++)

}// 如果沒有查詢過,則加入佇列

if (hasbeentrans == false) }}

}/*puts("-------------------");

for (int l = 0; l < possible_final_state_num; l++)

puts("");*/

bool accepted = false;

for (int j = 0; j < possible_final_state_num; j++)

}if (accepted)

else

} }return 0;

}

詞法分析 NFA語言識別

對於給出的nfa和輸入的字串,判斷字串是否是nfa識別的語言。輸入有多組資料。每組資料的第一行是兩個整數n n 50 和m m 27 表示nfa有n個狀態,以及字母表有m 1個字元。nfa的n個狀態用整數0 n 1表示,狀態0為起始狀態。字母表包含小寫英文本母的前m 1個字元。接下來的n行,每行有m...

NFA轉DFA程式設計

實驗二 利用子集構造法實現nfa到dfa的轉換 問題描述 利用子集構造法實現nfa到dfa的轉換。nfa的確定化 輸入形式 nfa 參見樣例。其中,第一列表示狀態名,終狀態用f表示 第二列和第三列分別表示輸入字元a和b所到達的狀態。輸出形式 dfa 參見樣例。其中,第一列表示輸入狀態名 第二列表示重...

NFA到DFA的轉換

include include include include include include define max 100 using namespace std struct edge struct newj 得到的狀態集合 struct relation 集合和集合之間的轉換聯絡 void g...