import javax.swing.* ;
import java.awt.* ;
import java.util.HashMap ;
import java.util.HashSet ;
import java.util.Map ;
import java.util.Set ;
public class Main
extends JFrame { private JTable transitionTable
; private JTextField initialStateField, finalStatesField, inputField
;
private Set< String> finalStates;
public Main( ) {
setTitle( "DFA Simulator" ) ;
setSize( 800 , 500 ) ;
setDefaultCloseOperation
( JFrame .
EXIT_ON_CLOSE ) ;
// Transition Table
String [ ] columnNames
= { "State" ,
"Input Symbol" ,
"Next State" } ; { "q1" , 'a' , "q2" } ,
{ "q1" , 'b' , "q1" } ,
{ "q2" , 'a' , "q2" } ,
{ "q2" , 'b' , "q3" } ,
{ "q3" , 'a' , "q1" } ,
{ "q3" , 'b' , "q1" }
} ;
transitionTable
= new JTable ( data, columnNames
) ;
// Output Area
outputArea.setEditable ( false ) ;
// Input Panel
inputPanel.
add ( new JLabel ( "Initial State:" ) ) ; inputPanel.add ( initialStateField) ;
inputPanel.
add ( new JLabel ( "Final States:" ) ) ; inputPanel.add ( finalStatesField) ;
inputPanel.
add ( new JLabel ( "Input:" ) ) ; inputPanel.add ( inputField) ;
simulateButton
= new JButton ( "Simulate" ) ; simulateButton.addActionListener ( e -> simulateDFA( ) ) ;
inputPanel.add ( simulateButton) ;
// Initialize DFA
initializeDFA( ) ;
setVisible( true ) ;
}
private void initializeDFA( ) {
transitionFunction = new HashMap<> ( ) ;
transitionFunction.put ( "q1" , new HashMap<> ( ) ) ;
transitionFunction.get ( "q1" ) .put ( 'a' , "q2" ) ;
transitionFunction.get ( "q1" ) .put ( 'b' , "q1" ) ;
transitionFunction.put ( "q2" , new HashMap<> ( ) ) ;
transitionFunction.get ( "q2" ) .put ( 'a' , "q2" ) ;
transitionFunction.get ( "q2" ) .put ( 'b' , "q3" ) ;
transitionFunction.put ( "q3" , new HashMap<> ( ) ) ;
transitionFunction.get ( "q3" ) .put ( 'a' , "q1" ) ;
transitionFunction.get ( "q3" ) .put ( 'b' , "q1" ) ;
finalStates = new HashSet<> ( ) ;
finalStates.add ( "q1" ) ;
finalStates.add ( "q3" ) ;
initialState = "q2" ;
}
private void simulateDFA( ) {
String input
= inputField.
getText ( ) ; String currentState
= initialStateField.
getText ( ) ; StringBuilder output = new StringBuilder( ) ;
for ( char symbol : input.toCharArray ( ) ) {
String nextState
= transitionFunction.
get ( currentState
) .
get ( symbol
) ; output.append ( currentState) .append ( "-" ) .append ( symbol) .append ( "->" ) .append ( nextState) .append ( " " ) ;
currentState = nextState;
}
output.append ( "\n " ) .append ( currentState) .append ( " is " ) ;
if ( finalStates.contains ( currentState) ) {
output.append ( "final ==> " ) .append ( input) .append ( " is accepted" ) ;
} else {
output.append ( "not final ==> " ) .append ( input) .append ( " is not accepted" ) ;
}
outputArea.setText ( output.toString ( ) ) ;
}
public static void main
( String [ ] args
) { }
}
aW1wb3J0IGphdmF4LnN3aW5nLio7CmltcG9ydCBqYXZhLmF3dC4qOwppbXBvcnQgamF2YS51dGlsLkhhc2hNYXA7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5NYXA7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwoKcHVibGljIGNsYXNzIE1haW4gZXh0ZW5kcyBKRnJhbWUgewogICAgcHJpdmF0ZSBKVGFibGUgdHJhbnNpdGlvblRhYmxlOwogICAgcHJpdmF0ZSBKVGV4dEFyZWEgb3V0cHV0QXJlYTsKICAgIHByaXZhdGUgSlRleHRGaWVsZCBpbml0aWFsU3RhdGVGaWVsZCwgZmluYWxTdGF0ZXNGaWVsZCwgaW5wdXRGaWVsZDsKICAgIHByaXZhdGUgSkJ1dHRvbiBzaW11bGF0ZUJ1dHRvbjsKCiAgICBwcml2YXRlIE1hcDxTdHJpbmcsIE1hcDxDaGFyYWN0ZXIsIFN0cmluZz4+IHRyYW5zaXRpb25GdW5jdGlvbjsKICAgIHByaXZhdGUgU2V0PFN0cmluZz4gZmluYWxTdGF0ZXM7CiAgICBwcml2YXRlIFN0cmluZyBpbml0aWFsU3RhdGU7CgogICAgcHVibGljIE1haW4oKSB7CiAgICAgICAgc2V0VGl0bGUoIkRGQSBTaW11bGF0b3IiKTsKICAgICAgICBzZXRTaXplKDgwMCwgNTAwKTsKICAgICAgICBzZXREZWZhdWx0Q2xvc2VPcGVyYXRpb24oSkZyYW1lLkVYSVRfT05fQ0xPU0UpOwogICAgICAgIHNldExheW91dChuZXcgQm9yZGVyTGF5b3V0KCkpOwoKICAgICAgICAvLyBUcmFuc2l0aW9uIFRhYmxlCiAgICAgICAgU3RyaW5nW10gY29sdW1uTmFtZXMgPSB7IlN0YXRlIiwgIklucHV0IFN5bWJvbCIsICJOZXh0IFN0YXRlIn07CiAgICAgICAgT2JqZWN0W11bXSBkYXRhID0gewogICAgICAgICAgICAgICAgeyJxMSIsICdhJywgInEyIn0sCiAgICAgICAgICAgICAgICB7InExIiwgJ2InLCAicTEifSwKICAgICAgICAgICAgICAgIHsicTIiLCAnYScsICJxMiJ9LAogICAgICAgICAgICAgICAgeyJxMiIsICdiJywgInEzIn0sCiAgICAgICAgICAgICAgICB7InEzIiwgJ2EnLCAicTEifSwKICAgICAgICAgICAgICAgIHsicTMiLCAnYicsICJxMSJ9CiAgICAgICAgfTsKICAgICAgICB0cmFuc2l0aW9uVGFibGUgPSBuZXcgSlRhYmxlKGRhdGEsIGNvbHVtbk5hbWVzKTsKICAgICAgICBhZGQobmV3IEpTY3JvbGxQYW5lKHRyYW5zaXRpb25UYWJsZSksIEJvcmRlckxheW91dC5OT1JUSCk7CgogICAgICAgIC8vIE91dHB1dCBBcmVhCiAgICAgICAgb3V0cHV0QXJlYSA9IG5ldyBKVGV4dEFyZWEoKTsKICAgICAgICBvdXRwdXRBcmVhLnNldEVkaXRhYmxlKGZhbHNlKTsKICAgICAgICBhZGQobmV3IEpTY3JvbGxQYW5lKG91dHB1dEFyZWEpLCBCb3JkZXJMYXlvdXQuQ0VOVEVSKTsKCiAgICAgICAgLy8gSW5wdXQgUGFuZWwKICAgICAgICBKUGFuZWwgaW5wdXRQYW5lbCA9IG5ldyBKUGFuZWwobmV3IEdyaWRMYXlvdXQoMywgMikpOwogICAgICAgIGlucHV0UGFuZWwuYWRkKG5ldyBKTGFiZWwoIkluaXRpYWwgU3RhdGU6IikpOwogICAgICAgIGluaXRpYWxTdGF0ZUZpZWxkID0gbmV3IEpUZXh0RmllbGQoInEyIik7CiAgICAgICAgaW5wdXRQYW5lbC5hZGQoaW5pdGlhbFN0YXRlRmllbGQpOwogICAgICAgIGlucHV0UGFuZWwuYWRkKG5ldyBKTGFiZWwoIkZpbmFsIFN0YXRlczoiKSk7CiAgICAgICAgZmluYWxTdGF0ZXNGaWVsZCA9IG5ldyBKVGV4dEZpZWxkKCJxMSxxMyIpOwogICAgICAgIGlucHV0UGFuZWwuYWRkKGZpbmFsU3RhdGVzRmllbGQpOwogICAgICAgIGlucHV0UGFuZWwuYWRkKG5ldyBKTGFiZWwoIklucHV0OiIpKTsKICAgICAgICBpbnB1dEZpZWxkID0gbmV3IEpUZXh0RmllbGQoImFiYWJiYiIpOwogICAgICAgIGlucHV0UGFuZWwuYWRkKGlucHV0RmllbGQpOwogICAgICAgIHNpbXVsYXRlQnV0dG9uID0gbmV3IEpCdXR0b24oIlNpbXVsYXRlIik7CiAgICAgICAgc2ltdWxhdGVCdXR0b24uYWRkQWN0aW9uTGlzdGVuZXIoZSAtPiBzaW11bGF0ZURGQSgpKTsKICAgICAgICBpbnB1dFBhbmVsLmFkZChzaW11bGF0ZUJ1dHRvbik7CiAgICAgICAgYWRkKGlucHV0UGFuZWwsIEJvcmRlckxheW91dC5TT1VUSCk7CgogICAgICAgIC8vIEluaXRpYWxpemUgREZBCiAgICAgICAgaW5pdGlhbGl6ZURGQSgpOwoKICAgICAgICBzZXRWaXNpYmxlKHRydWUpOwogICAgfQoKICAgIHByaXZhdGUgdm9pZCBpbml0aWFsaXplREZBKCkgewogICAgICAgIHRyYW5zaXRpb25GdW5jdGlvbiA9IG5ldyBIYXNoTWFwPD4oKTsKICAgICAgICB0cmFuc2l0aW9uRnVuY3Rpb24ucHV0KCJxMSIsIG5ldyBIYXNoTWFwPD4oKSk7CiAgICAgICAgdHJhbnNpdGlvbkZ1bmN0aW9uLmdldCgicTEiKS5wdXQoJ2EnLCAicTIiKTsKICAgICAgICB0cmFuc2l0aW9uRnVuY3Rpb24uZ2V0KCJxMSIpLnB1dCgnYicsICJxMSIpOwogICAgICAgIHRyYW5zaXRpb25GdW5jdGlvbi5wdXQoInEyIiwgbmV3IEhhc2hNYXA8PigpKTsKICAgICAgICB0cmFuc2l0aW9uRnVuY3Rpb24uZ2V0KCJxMiIpLnB1dCgnYScsICJxMiIpOwogICAgICAgIHRyYW5zaXRpb25GdW5jdGlvbi5nZXQoInEyIikucHV0KCdiJywgInEzIik7CiAgICAgICAgdHJhbnNpdGlvbkZ1bmN0aW9uLnB1dCgicTMiLCBuZXcgSGFzaE1hcDw+KCkpOwogICAgICAgIHRyYW5zaXRpb25GdW5jdGlvbi5nZXQoInEzIikucHV0KCdhJywgInExIik7CiAgICAgICAgdHJhbnNpdGlvbkZ1bmN0aW9uLmdldCgicTMiKS5wdXQoJ2InLCAicTEiKTsKCiAgICAgICAgZmluYWxTdGF0ZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgZmluYWxTdGF0ZXMuYWRkKCJxMSIpOwogICAgICAgIGZpbmFsU3RhdGVzLmFkZCgicTMiKTsKCiAgICAgICAgaW5pdGlhbFN0YXRlID0gInEyIjsKICAgIH0KCiAgICBwcml2YXRlIHZvaWQgc2ltdWxhdGVERkEoKSB7CiAgICAgICAgU3RyaW5nIGlucHV0ID0gaW5wdXRGaWVsZC5nZXRUZXh0KCk7CiAgICAgICAgU3RyaW5nIGN1cnJlbnRTdGF0ZSA9IGluaXRpYWxTdGF0ZUZpZWxkLmdldFRleHQoKTsKICAgICAgICBTdHJpbmdCdWlsZGVyIG91dHB1dCA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CgogICAgICAgIGZvciAoY2hhciBzeW1ib2wgOiBpbnB1dC50b0NoYXJBcnJheSgpKSB7CiAgICAgICAgICAgIFN0cmluZyBuZXh0U3RhdGUgPSB0cmFuc2l0aW9uRnVuY3Rpb24uZ2V0KGN1cnJlbnRTdGF0ZSkuZ2V0KHN5bWJvbCk7CiAgICAgICAgICAgIG91dHB1dC5hcHBlbmQoY3VycmVudFN0YXRlKS5hcHBlbmQoIi0iKS5hcHBlbmQoc3ltYm9sKS5hcHBlbmQoIi0+IikuYXBwZW5kKG5leHRTdGF0ZSkuYXBwZW5kKCIgIik7CiAgICAgICAgICAgIGN1cnJlbnRTdGF0ZSA9IG5leHRTdGF0ZTsKICAgICAgICB9CgogICAgICAgIG91dHB1dC5hcHBlbmQoIlxuIikuYXBwZW5kKGN1cnJlbnRTdGF0ZSkuYXBwZW5kKCIgaXMgIik7CiAgICAgICAgaWYgKGZpbmFsU3RhdGVzLmNvbnRhaW5zKGN1cnJlbnRTdGF0ZSkpIHsKICAgICAgICAgICAgb3V0cHV0LmFwcGVuZCgiZmluYWwgPT0+ICIpLmFwcGVuZChpbnB1dCkuYXBwZW5kKCIgaXMgYWNjZXB0ZWQiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvdXRwdXQuYXBwZW5kKCJub3QgZmluYWwgPT0+ICIpLmFwcGVuZChpbnB1dCkuYXBwZW5kKCIgaXMgbm90IGFjY2VwdGVkIik7CiAgICAgICAgfQoKICAgICAgICBvdXRwdXRBcmVhLnNldFRleHQob3V0cHV0LnRvU3RyaW5nKCkpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKICAgICAgICBTd2luZ1V0aWxpdGllcy5pbnZva2VMYXRlcigoKSAtPiBuZXcgTWFpbigpLnNldFZpc2libGUodHJ1ZSkpOwogICAgfQp9