对任意给定的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);
}
}
运行结果图片