/** *author Young * *2014-5-11 * */ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Scanner; import java.util.Set; import java.util.TreeSet; public class NFAtoDFA { static String map[][]; static int endNum; //保存所有状态 static ArrayList<Set<Integer>>list=new ArrayList<Set<Integer>>(); //输入符号列 static ArrayList<String>operatorList=new ArrayList<String>(); //fromSetToSet中每个元素对应 list中从哪个状态下标到哪个状态下表经过的符号及对应下标 static ArrayList<SetOperatorSet>fromSetToSet=new ArrayList<SetOperatorSet>(); static Scanner sc=new Scanner(System.in); public static void main(String[] args) { System.out.println("输入终结符号(最大值)"); //默认最大值是终结 0是开始 endNum=sc.nextInt(); map=new String[endNum+1][endNum+1]; initMap(); System.out.println("输入符号集(空格分隔,e代表可自动到达)"); sc.nextLine(); String line=sc.nextLine(); for(String str:line.split(" +")) { operatorList.add(str); } System.out.println(); int s,e; String operator; //-1表示输入结束 while(sc.hasNext()) { s=sc.nextInt(); if(s==-1) break; operator=sc.next(); e=sc.nextInt(); map[s][e]=operator; } //把第一个状态加入list list.add(getSetStartWith(0)); for(int i=0;i<list.size();i++) { Set<Integer> set=list.get(i); //======把符号作用于集合======= for(String ope:operatorList) { if(ope.equals("e")) continue; Iterator<Integer> iter=set.iterator(); //set2 保存从某一集合(list中)经过某一符号达到的所有集合组成的集合 Set<Integer> set2=new TreeSet<Integer>(); //依次把该符号作用于该集合的每一个数字 while(iter.hasNext()) { //每次获取该集合中一个数字 int fromNum=iter.next(); //获取从该数字经过ope到达的数字 -1表示不达到 int toNum=getIndexFromWithOperatorTo(fromNum,ope); if(toNum==-1) continue; //获取从toNum开始的可自动到达的集合,并加入set2 set2.addAll(getSetStartWith(toNum)); } //若list中存在该状态集合 if(list.contains(set2)) { //找到list中该状态集合下标 int index=list.indexOf(set2); //结果列表中添加由list中第i个状态经ope达到list中第index个状态 fromSetToSet.add(new SetOperatorSet(i, index, ope)); } else { if(set2.size()!=0) { //若list中原本没有改状态,则把新状态加入list,并把list中第i个状态经ope达到list中最后一个状态 list.add(set2); fromSetToSet.add(new SetOperatorSet(i, list.size()-1, ope)); } } } //======把符号作用于集合结束======= } showResult(); ////////////===============NFA 化 DFA 结束 ======================/////////////// ///==================化简 DFA=======================///// new SimpleDFA( endNum, list, operatorList, fromSetToSet).start(); } private static void initMap() { for(int i=0;i<endNum+1;i++) for(int j=0;j<endNum+1;j++) map[i][j]=""; } private static void showResult() { for(int i=0;i<list.size();i++) { System.out.println(i+1+" "+list.get(i)); } Collections.sort(fromSetToSet); System.out.println("\n\n"); for(SetOperatorSet li:fromSetToSet) { System.out.println(li.fromListIndex+1+" "+li.operator+" "+(li.toListIndex+1)); } System.out.println("\n\n==========\n"); } //获取map中从fromNum经过ope到达的数字 -1表示无法达到 private static int getIndexFromWithOperatorTo(int fromNum, String ope) { for(int i=0;i<endNum+1;i++) { if(map[fromNum][i].equals(ope)) return i; } return -1; } //获取从s开始可自动达到的集合 private static Set<Integer> getSetStartWith(int s) { Set<Integer> set=new TreeSet<Integer>(); set.add(s); DFS(s,set); return set; } //搜索从s开始可自动达到的集合 private static void DFS(int s,Set<Integer> set) { for(int i=0;i<=endNum;i++) { if(map[s][i].equals("e")&&!set.contains(i)) { set.add(i); DFS(i,set); } } } } class SetOperatorSet implements Comparable<SetOperatorSet>{ public int fromListIndex; public int toListIndex; public String operator; public SetOperatorSet(int fromListIndex, int toListIndex, String operator) { this.fromListIndex = fromListIndex; this.toListIndex = toListIndex; this.operator = operator; } @Override public boolean equals(Object obj) { SetOperatorSet sos=(SetOperatorSet)obj; if(this.fromListIndex==sos.fromListIndex&&this.toListIndex==sos.toListIndex&&this.operator.equals(sos.operator)) return true; return false; } @Override public int compareTo(SetOperatorSet o) { // return this.operator.compareTo(o.operator); // if(this.fromListIndex==o.fromListIndex&&this.toListIndex==o.toListIndex&&this.operator.equals(o.operator)) // return 0; return this.fromListIndex-o.fromListIndex; } @Override public String toString() { return fromListIndex+ " "+operator+" "+toListIndex; } } import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeSet; public class SimpleDFA { int endNum; //保存所有状态 ArrayList<Set<Integer>>list; //输入符号列 ArrayList<String>operatorList; //fromSetToSet中每个元素对应 list中从哪个状态下标到哪个状态下表经过的符号及对应下标 ArrayList<SetOperatorSet>fromSetToSet; ArrayList<Set<Integer>>result=new ArrayList<Set<Integer>>(); ArrayList<Set<Integer>>tempList=new ArrayList<Set<Integer>>(); public SimpleDFA(int endNum, ArrayList<Set<Integer>> list,ArrayList<String> operatorList,ArrayList<SetOperatorSet> fromSetToSet) { this.endNum = endNum; this.list = list; this.operatorList = operatorList; this.fromSetToSet = fromSetToSet; } public void start() { DividedSetByEndNum(); for(int i=0;i<tempList.size();i++) { Set<Integer>set=tempList.get(i); int j; for( j=0;j<operatorList.size();j++) { if(operatorList.get(j).equals("e")) continue; if(needDivided(i,set,operatorList.get(j))) { break; } } if(j>=operatorList.size()) { result.add(set); } } showResult(); } private void showResult() { System.out.println("\n\n========最简化DFA===\n"); for(int i=0;i<result.size();i++) { System.out.println( result.get(i)); } for(int i=0;i<result.size();i++) { Set<Integer>set=result.get(i); if(set.size()==1) continue; Iterator<Integer>itr=set.iterator(); int firstInSet=itr.next()-1; while(itr.hasNext()) { int next=itr.next()-1; for(int j=0;j<fromSetToSet.size();j++) { SetOperatorSet sos=fromSetToSet.get(j); if(sos.fromListIndex==next) { sos.fromListIndex=firstInSet; } if(sos.toListIndex==next) { sos.toListIndex=firstInSet; } } } } // System.out.println("\n替换完毕\n"); // for(int j=0;j<fromSetToSet.size();j++) // { // SetOperatorSet li=fromSetToSet.get(j); // System.out.println(li.fromListIndex+" "+li.operator+" "+(li.toListIndex)); // } ArrayList<SetOperatorSet>sosSet=new ArrayList<SetOperatorSet>(); for(SetOperatorSet sos:fromSetToSet) { // System.out.print(sos); if(!sosSet.contains(sos)) sosSet.add(sos); } System.out.println("========最终结果========="); for(SetOperatorSet sos:sosSet) { System.out.println(sos.fromListIndex+1+" "+sos.operator+" "+(1+sos.toListIndex)); } } private boolean needDivided(int i,Set<Integer> set, String ope2) { Set<Integer>set2=new TreeSet<Integer>(); Map<Integer,Set<Integer>>map=new HashMap<Integer,Set<Integer>>(); Iterator<Integer>itr=set.iterator(); while(itr.hasNext()) { int fromStatue=itr.next(); int toStatue=getFromByOperatorTo( fromStatue, ope2); if(toStatue==-1) continue; int aimStatuIndex=getAimStatuIndexByReaultAndTempList(i,toStatue); if(set2.add(aimStatuIndex)) { Set<Integer> set3=new TreeSet<Integer>(); set3.add(fromStatue); map.put(aimStatuIndex, set3); } else { Set<Integer> set3=map.get(aimStatuIndex); set3.add(fromStatue); } } if(set2.size()<=1) { return false; } Iterator<Integer>iterator=set2.iterator(); while(iterator.hasNext()) { int index=iterator.next(); Set<Integer> s=map.get(index); if(s.size()==1) { result.add(s); } else { tempList.add(s); } } return true; } private int getAimStatuIndexByReaultAndTempList(int i,int toStatue) { for(;i<tempList.size();i++) { Set<Integer>set=tempList.get(i); if(set.contains(toStatue)) return i; } for(int j=0;j<result.size();j++) { Set<Integer>set=result.get(j); if(set.contains(toStatue)) return -j-1; } return Integer.MAX_VALUE; } private void DividedSetByEndNum() { Set<Integer>endSet=new TreeSet<Integer>(); Set<Integer>unEndSet=new TreeSet<Integer>(); for(int i=0;i<list.size();i++) { Set<Integer>s=list.get(i); if(s.contains(endNum)) { endSet.add(i+1); } else unEndSet.add(i+1); } tempList.add(unEndSet); tempList.add(endSet); } private int getFromByOperatorTo(int sStatu, String ope) { for(int i=0;i<fromSetToSet.size();i++) { SetOperatorSet sos=fromSetToSet.get(i); if(sos.fromListIndex+1==sStatu&&sos.operator.equals(ope)) return sos.toListIndex+1; } return -1; } } /* 测试样例 10 e a b 0 e 1 0 e 7 1 e 2 1 e 4 2 a 3 4 b 5 3 e 6 5 e 6 6 e 1 6 e 7 7 a 8 8 b 9 9 b 10 -1 ================== 1 [0, 1, 2, 4, 7] 2 [1, 2, 3, 4, 6, 7, 8] 3 [1, 2, 4, 5, 6, 7] 4 [1, 2, 4, 5, 6, 7, 9] 5 [1, 2, 4, 5, 6, 7, 10] 1 a 2 1 b 3 2 a 2 2 b 4 3 a 2 3 b 3 4 a 2 4 b 5 5 a 2 5 b 3 ========== ========最简化DFA=== [4] [5] [2] [1, 3] ========== ========最终结果========= 1 a 2 1 b 1 2 a 2 2 b 4 4 a 2 4 b 5 5 a 2 5 b 1 ================== 测试样例 13 e a b 0 e 1 0 e 3 1 b 2 2 e 1 2 e 3 3 a 4 4 b 5 5 e 6 6 e 13 6 e 7 6 e 9 7 b 8 8 e 12 9 a 10 10 b 11 11 e 12 12 e 13 12 e 6 -1 ===================== 1 [0, 1, 3] 2 [4] 3 [1, 2, 3] 4 [5, 6, 7, 9, 13] 5 [10] 6 [6, 7, 8, 9, 12, 13] 7 [6, 7, 9, 11, 12, 13] 1 a 2 1 b 3 2 b 4 3 a 2 3 b 3 4 a 5 4 b 6 5 b 7 6 a 5 6 b 6 7 a 5 7 b 6 ========== ========最简化DFA=== [4, 6, 7] [1, 3] [2, 5] ========== ========最终结果========= 1 a 2 1 b 1 2 b 4 4 a 2 4 b 4 */
NFA->DFA->最简DFA,布布扣,bubuko.com
原文地址:http://blog.csdn.net/qingchunweiliang/article/details/25789977