soj-1001. NFA識別語言
Description
對於給出的NFA和輸入的字串,判斷字串是否是NFA識別的語言。
Input
輸入有多組資料。每組資料的第一行是兩個整數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表示輸入結束。
Output
對於每個待識別的字串,如果能被給出的NFA識別,輸出YES;否則輸出NO。
Sample Input
4 3
{} {0,1} {0}
{} {} {2}
{} {} {3}
{} {} {}
3 -1
aaabb
abbab
abbaaabb
abbb
#
0 0
Sample Output
YES
NO
YES
NO
Hint
輸入樣例是課本Figure 3.24的NFA。你需要實現的是課本Figure 3.33和3.37的演算法。
思路
模擬。
基本思路和DFA一樣,不過我們要考慮空狀態的轉移,以及我們需要存一個狀態集而不是一個狀態。
程式碼
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
int n, m, accept_num;
char alphabet[27];
int accept[51];
int map[50][27][51];
int state[50];
int state1[50];
int statenum, state1num;
string s;
bool check;
void init(int n, int m){
string s;
int num, temp;
for(int i = 0; i < n; ++i){
for(int j = 0; j < m; ++j){
cin>>s;
num = -1;
temp = 1;
for(int k = 0; k < s.size(); ++k){
if(s[k] >= '0' && s[k] <= '9'){
if (num == -1){
num = s[k] - '0';
}
else{
num = num * 10 + s[k] - '0';
}
}
else{
if(num != -1){
map[i][j][0]++;
map[i][j][temp++] = num;
num = -1;
}
}
}
map[i][j][0] = temp - 1;
}
}
for (accept_num = 0; accept_num < 51; accept_num++) {
cin >> accept[accept_num];
if (accept[accept_num] == -1) break;
}
}
int main(){
alphabet[0] = 'A';
for(int i = 1;i < 27; ++i){
alphabet[i] = 97 + i;
}
while((cin>>n>>m) && n != 0 && m != 0){
init(n,m);
while(1){
int state2;
cin>>s;
check = 0;
if(s == "#")break;
memset(state, 0, sizeof(state));
statenum = 1;
state1num = 0;
for(int i = 0; i< s.size(); ++i){
for(int j = 0; j < statenum; ++j){
for(int k = 0; k < map[state[j]][0][0]; ++k){
state2 = map[state[j]][0][k+1];
bool get = 0;
for (int l = 0; l < statenum; ++l){
if(state[l] == state2)get = 1;
}
if(!get){
state[statenum++] = state2;
}
}
for(int k = 0; k < map[state[j]][s[i]-96][0]; ++k){
state2 = map[state[j]][s[i]-96][k+1];
bool get = 0;
for(int l = 0; l < state1num; ++l){
if(state[l] == state2)get = 1;
}
if(!get){
state1[state1num++] = state2;
}
}
}
for(int j = 0; j < state1num; ++j){
state[j] = state1[j];
}
statenum = state1num;
state1num = 0;
for(int j = 0; j < statenum; ++j){
int state2;
for(int k = 0; k < map[state[j]][0][0]; ++k){
state2 = map[state[j]][0][k+1];
bool get = 0;
for (int l = 0; l < statenum; ++l){
if(state[l] == state2)get = 1;
}
if(!get){
state[statenum++] = state2;
}
}
}
}
for(int i = 0; i < accept_num; ++i){
for (int j = 0; j < statenum; ++j){
if(state[j] == accept[i]){
check = 1;
break;
}
}
}
if(check){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
}
return 0;
}
相關文章
- C語言-識別符號命名C語言符號
- SpeechRecognition麥克風語言識別
- 1413: C語言合法識別符號C語言符號
- IJCAI 2018 利用跨語言知識改進稀缺資源語言命名實體識別AI
- C語言合法識別符號 hd 2024C語言符號
- 概念區別 【編譯型語言與解釋型語言、動態型別語言與靜態型別語言、強型別語言與弱型別語言】編譯型別
- 使用Rust語言實現基本影像識別Rust
- 使用Scala語言實現基本影像識別
- 使用Haskell語言實現基本影像識別Haskell
- 使用Lua語言實現基本影像識別
- 利用 D 程式語言實現文字識別程式
- Go語言————1、初識GO語言Go
- 有道自然語言翻譯和文字識別OCR(圖片文字識別)介面呼叫
- Pyhanlp自然語言處理中的新詞識別HanLP自然語言處理
- 分享一個自然語言漢語時間語義識別的工具類
- Go語言的識別符號、關鍵字、字面量、型別Go符號型別
- 語言型別介紹及其Python的語言型別型別Python
- 初識C語言C語言
- 初識go語言Go
- 計算機語言:編譯型/解釋型、動態語言/靜態語言、強型別語言/弱型別語言計算機編譯型別
- 用於影像識別的五大最佳程式語言!
- 微調大型語言模型進行命名實體識別模型
- 使用 R 語言實現簡單的文字識別程式
- 使用 Go 語言實現簡單的文字識別(OCR)Go
- 初識Go語言-1Go
- 快商通首席科學家:語音識別的後半段路,從語言處理走向語言理解
- GO語言————4.1 檔名、關鍵字與識別符號Go符號
- hanlp自然語言處理包的人名識別程式碼解析HanLP自然語言處理
- 形式語言與自動機:實驗二——DFA識別句子
- 自然語言處理工具python呼叫hanlp中文實體識別自然語言處理PythonHanLP
- go語言簡單入門--常識和資料型別Go資料型別
- 解釋型語言、編譯型語言 區別編譯
- Solidity語言學習筆記————1、初識Solidity語言Solid筆記
- 那些主流程式語言的知識,C語言(Ⅰ)C語言
- 語音識別模型模型
- C語言知識彙總 | 00-C語言知識彙總目錄C語言
- Python 語言特性:編譯+解釋、動態型別語言、動態語言Python編譯型別
- c語言基礎知識C語言