对任意给定的NFA M进行确定化操作(附详细注释)
DFA实体类
package Beans ;
import java. util. List ;
public class DFA {
private List < Integer > K ;
private char [ ] letters;
private String [ ] [ ] f;
private int S ;
private List < Integer > Z ;
public List < Integer > getK ( ) {
return K ;
}
public void setK ( List < Integer > k) {
K = k;
}
public char [ ] getLetters ( ) {
return letters;
}
public void setLetters ( char [ ] letters) {
this . letters = letters;
}
public String [ ] [ ] getF ( ) {
return f;
}
public void setF ( String [ ] [ ] f) {
this . f = f;
}
public int getS ( ) {
return S ;
}
public void setS ( int s) {
S = s;
}
public List < Integer > getZ ( ) {
return Z ;
}
public void setZ ( List < Integer > z) {
Z = z;
}
}
NFA实体类
package Beans ;
import java. util. List ;
public class NFA {
private List < Integer > K ;
private char [ ] letters;
private String [ ] [ ] f;
private List < Integer > S ;
private List < Integer > Z ;
public List < Integer > getK ( ) {
return K ;
}
public void setK ( List < Integer > k) {
K = k;
}
public char [ ] getLetters ( ) {
return letters;
}
public void setLetters ( char [ ] letters) {
this . letters = letters;
}
public String [ ] [ ] getF ( ) {
return f;
}
public void setF ( String [ ] [ ] f) {
this . f = f;
}
public List < Integer > getS ( ) {
return S ;
}
public void setS ( List < Integer > s) {
S = s;
}
public List < Integer > getZ ( ) {
return Z ;
}
public void setZ ( List < Integer > z) {
Z = z;
}
}
NFA转换成DFA方法类(NFA2DFA)
package Service ;
import Beans . DFA;
import Beans . NFA;
import java. util. * ;
public class NFA2DFA {
public DFA definite ( NFA nfa) {
List < Integer > K0 = nfa. getS ( ) ;
char [ ] letters = nfa. getLetters ( ) ;
String [ ] [ ] f = nfa. getF ( ) ;
List < Integer > Z = nfa. getZ ( ) ;
DFA dfa = new DFA ( ) ;
List < Integer > K = new ArrayList < > ( ) ;
int k = 0 ;
List < String [ ] > listF = new ArrayList < > ( ) ;
List < Integer > listZ = new ArrayList < > ( ) ;
StringBuilder sb = new StringBuilder ( ) ;
Set < List < Integer > > set = new HashSet < > ( ) ;
Queue < List < Integer > > queue = new LinkedList < > ( ) ;
Map < List < Integer > , Integer > map = new HashMap < > ( ) ;
List < Integer > closure_K = closure ( K0, f) ;
K . add ( k) ;
map. put ( closure_K, k++ ) ;
queue. add ( closure_K) ;
while ( ! queue. isEmpty ( ) ) {
List < Integer > I = queue. poll ( ) ;
for ( char letter : letters) {
List < Integer > nextI = closure ( move ( I , letter, f) , f) ;
if ( nextI. isEmpty ( ) ) continue ;
if ( ! containsI ( set, nextI) ) {
nextI. sort ( Comparator . comparing ( Integer :: intValue ) ) ;
map. put ( nextI, k) ;
K . add ( k) ;
if ( ! Collections . disjoint ( nextI, Z ) ) {
listZ. add ( k) ;
}
set. add ( nextI) ;
queue. add ( nextI) ;
k++ ;
}
System . out. print ( I ) ;
System . out. println ( nextI) ;
listF. add ( new String [ ] { String . valueOf ( map. get ( I ) ) , String . valueOf ( letter) , String . valueOf ( map. get ( nextI) ) } ) ;
sb. append ( map. get ( I ) ) . append ( letter) . append ( map. get ( nextI) ) . append ( '\n' ) ;
}
}
System . out. println ( "重命名后:" ) ;
System . out. println ( sb. toString ( ) ) ;
int len = K . size ( ) ;
String [ ] [ ] f2 = new String [ len] [ len] ;
for ( String [ ] tmp : f2) {
Arrays . fill ( tmp, "" ) ;
}
for ( String [ ] arr : listF) {
f2[ Integer . parseInt ( arr[ 0 ] ) ] [ Integer . parseInt ( arr[ 2 ] ) ] += arr[ 1 ] ;
}
dfa. setK ( K ) ;
dfa. setLetters ( letters) ;
dfa. setF ( f2) ;
dfa. setS ( 0 ) ;
dfa. setZ ( listZ) ;
return dfa;
}
private List < Integer > closure ( List < Integer > I , String [ ] [ ] f) {
List < Integer > closureI = new ArrayList < > ( ) ;
Queue < Integer > queue = new LinkedList < > ( ) ;
for ( int i : I ) {
queue. add ( i) ;
while ( ! queue. isEmpty ( ) ) {
int n = queue. poll ( ) ;
for ( int iNext = 0 ; iNext < f. length; iNext++ ) {
for ( char c : f[ n] [ iNext] . toCharArray ( ) ) {
if ( c == 'ε' && ! closureI. contains ( iNext) ) {
closureI. add ( iNext) ;
if ( n != iNext) {
queue. add ( iNext) ;
}
}
}
}
}
}
return closureI;
}
private List < Integer > move ( List < Integer > I , char letter, String [ ] [ ] f) {
List < Integer > nextI = new ArrayList < > ( ) ;
for ( int i : I ) {
for ( int iNext = 0 ; iNext < f. length; iNext++ ) {
for ( char c : f[ i] [ iNext] . toCharArray ( ) ) {
if ( c == letter && ! nextI. contains ( iNext) ) {
nextI. add ( iNext) ;
}
}
}
}
return nextI;
}
private boolean containsI ( Set < List < Integer > > set, List < Integer > list) {
for ( List < Integer > l : set) {
if ( listEquals ( l, list) ) {
return true ;
}
}
return false ;
}
private boolean listEquals ( List < Integer > list1, List < Integer > list2) {
list1. sort ( Comparator . comparing ( Integer :: intValue ) ) ;
list2. sort ( Comparator . comparing ( Integer :: intValue ) ) ;
return list1. toString ( ) . equals ( list2. toString ( ) ) ;
}
}
输入函数类
package Utils ;
import Beans . DFA;
import Beans . NFA;
import java. io. BufferedReader ;
import java. io. IOException ;
import java. io. InputStreamReader ;
import java. util. ArrayList ;
import java. util. Arrays ;
import java. util. List ;
import java. util. Scanner ;
public class EnterUtils {
private static int n;
public static void enterK ( NFA nfa) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in) ) ;
List < Integer > list = new ArrayList < > ( ) ;
String [ ] strings = br. readLine ( ) . split ( "" ) ;
for ( String s : strings) {
list. add ( Integer . parseInt ( s) ) ;
}
n = list. size ( ) ;
nfa. setK ( list) ;
}
public static void enterLetters ( NFA nfa) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in) ) ;
char [ ] letters = br. readLine ( ) . toCharArray ( ) ;
nfa. setLetters ( letters) ;
}
public static void enterF ( NFA nfa) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in) ) ;
String [ ] [ ] f = new String [ n] [ n] ;
for ( String [ ] arr : f) {
Arrays . fill ( arr, "" ) ;
}
for ( int i = 0 ; i < f. length; i++ ) {
f[ i] [ i] = "ε" ;
}
String line = "" ;
while ( ! ( line = br. readLine ( ) . trim ( ) ) . equals ( "end" ) ) {
String [ ] arr = line. split ( "" ) ;
f[ Integer . parseInt ( arr[ 0 ] ) ] [ Integer . parseInt ( arr[ 2 ] ) ] += arr[ 1 ] ;
}
nfa. setF ( f) ;
}
public static void enterS ( NFA nfa) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in) ) ;
List < Integer > list = new ArrayList < > ( ) ;
String [ ] strings = br. readLine ( ) . split ( "" ) ;
for ( String s : strings) {
list. add ( Integer . parseInt ( s) ) ;
}
nfa. setS ( list) ;
}
public static void enterZ ( NFA nfa) throws IOException {
BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in) ) ;
List < Integer > list = new ArrayList < > ( ) ;
String [ ] strings = br. readLine ( ) . split ( "" ) ;
for ( String s : strings) {
list. add ( Integer . parseInt ( s) ) ;
}
nfa. setZ ( list) ;
}
}
输出函数类
package Utils ;
import Beans . DFA;
import Beans . NFA;
import java. util. Arrays ;
public class DisplayUtils {
public static void displayK ( NFA nfa) {
System . out. println ( nfa. getK ( ) ) ;
}
public static void displayLetters ( NFA nfa) {
System . out. println ( Arrays . toString ( nfa. getLetters ( ) ) ) ;
}
public static void displayF ( NFA nfa) {
String [ ] [ ] f = nfa. getF ( ) ;
for ( int i = 0 ; i < f. length; i++ ) {
for ( int j = 0 ; j < f. length; j++ ) {
if ( f[ i] [ j] == "" ) continue ;
for ( char c : f[ i] [ j] . toCharArray ( ) ) {
if ( i == j && c == 'ε' ) continue ;
StringBuilder sb = new StringBuilder ( ) . append ( i) . append ( c) . append ( j) . append ( " " ) ;
System . out. print ( sb. toString ( ) ) ;
}
}
}
System . out. println ( ) ;
}
public static void displayS ( NFA nfa) {
System . out. println ( nfa. getS ( ) ) ;
}
public static void displayZ ( NFA nfa) {
System . out. println ( nfa. getZ ( ) ) ;
}
public static void displayK ( DFA dfa) {
System . out. println ( dfa. getK ( ) ) ;
}
public static void displayLetters ( DFA dfa) {
System . out. println ( Arrays . toString ( dfa. getLetters ( ) ) ) ;
}
public static void displayF ( DFA dfa) {
String [ ] [ ] f = dfa. getF ( ) ;
for ( int i = 0 ; i < f. length; i++ ) {
for ( int j = 0 ; j < f. length; j++ ) {
if ( f[ i] [ j] == "" ) continue ;
for ( char c : f[ i] [ j] . toCharArray ( ) ) {
StringBuilder sb = new StringBuilder ( ) . append ( i) . append ( c) . append ( j) . append ( " " ) ;
System . out. print ( sb. toString ( ) ) ;
}
}
}
System . out. println ( ) ;
}
public static void displayS ( DFA dfa) {
System . out. println ( dfa. getS ( ) ) ;
}
public static void displayZ ( DFA dfa) {
System . out. println ( dfa. getZ ( ) ) ;
}
}
测试类
package Test ;
import Beans . DFA;
import Beans . NFA;
import Service . NFA2DFA;
import Utils. DisplayUtils ;
import Utils. EnterUtils ;
import java. io. IOException ;
public class Test_NFA2DFA {
public static void main ( String [ ] args) throws IOException {
NFA nfa = new NFA ( ) ;
System . out. print ( "请输入NFA状态集:" ) ; EnterUtils . enterK ( nfa) ;
System . out. print ( "请输入NFA字母表:" ) ; EnterUtils . enterLetters ( nfa) ;
System . out. print ( "请输入NFA状态转换函数:" ) ; EnterUtils . enterF ( nfa) ;
System . out. print ( "请输入NFA初态集:" ) ; EnterUtils . enterS ( nfa) ;
System . out. print ( "请输入NFA终态集:" ) ; EnterUtils . enterZ ( nfa) ;
DFA dfa = new NFA2DFA ( ) . definite ( nfa) ;
System . out. print ( "DFA状态集:" ) ; DisplayUtils . displayK ( dfa) ;
System . out. print ( "DFA字母表:" ) ; DisplayUtils . displayLetters ( dfa) ;
System . out. print ( "DFA状态转换函数:" ) ; DisplayUtils . displayF ( dfa) ;
System . out. print ( "DFA唯一初态:" ) ; DisplayUtils . displayS ( dfa) ;
System . out. print ( "DFA终态集:" ) ; DisplayUtils . displayZ ( dfa) ;
}
}
运行结果图片