DFA of a string in which 2nd symbol from RHS is ‘a’
Last Updated :
02 Feb, 2024
Draw deterministic finite automata (DFA) of the language containing the set of all strings over {a, b} in which 2nd symbol from RHS is ‘a’. The strings in which 2nd last symbol is “a” are:
aa, ab, aab, aaa, aabbaa, bbbab etc
Input/Output
INPUT : baba
OUTPUT: NOT ACCEPTED
INPUT: aaab
OUTPUT: ACCEPTED
Constructing the DFA of the given problem directly is very complicated. So, here we are going to design the non-deterministic finite automata (NFA) and then convert it to the deterministic finite automata (DFA). The NFA of the language containing all the strings in which 2nd symbol from the RHS is “a” is:
![NFA](https://media.geeksforgeeks.org/wp-content/uploads/NFA1.png)
Here, A is the initial state and C is the final state. Now, we are going to construct the state transition table of the above NFA.
![State Transition Diagram 1](https://media.geeksforgeeks.org/wp-content/uploads/DFA1.png)
After that we will draw the state transition table of DFA using subset configuration on the state transition table of NFA. We will mention all the possible transition for a and b.
![State Transition Diagram 2](https://media.geeksforgeeks.org/wp-content/uploads/DFA1-1.png)
Now it’s become very easy to draw the DFA with the help of its transition table. In this DFA, we have four different states A, AB, ABC and AC, where ABC and AC are the final states and A is the initial state of the DFA.
![DFA](https://media.geeksforgeeks.org/wp-content/uploads/DFA1-2.png)
This is our required DFA of the language containing the set of all strings over {a, b} in which 2nd symbol from RHS is ‘a’.
Transition Table
—> A (initial state) |
AB |
A |
AB |
ABC* (final state) |
AC* (final state) |
AC* (final state) |
AB |
A |
ABC* (final state) |
ABC* (final state) |
AC* (final state) |
C++ & Python Implementation
C++
#include <iostream>
using namespace std;
void stateA(string n);
void stateAB(string n);
void stateABC(string n);
void stateAC(string n);
void stateA(string n) {
if (n.length() == 0) {
cout << "string not accepted" << endl;
} else {
if (n[0] == 'a' ) {
stateAB(n.substr(1));
} else if (n[0] == 'b' ) {
stateA(n.substr(1));
}
}
}
void stateAB(string n) {
if (n.length() == 0) {
cout << "string not accepted" << endl;
} else {
if (n[0] == 'a' ) {
stateABC(n.substr(1));
} else if (n[0] == 'b' ) {
stateAC(n.substr(1));
}
}
}
void stateABC(string n) {
if (n.length() == 0) {
cout << "string accepted" << endl;
} else {
if (n[0] == 'a' ) {
stateABC(n.substr(1));
} else if (n[0] == 'b' ) {
stateAC(n.substr(1));
}
}
}
void stateAC(string n) {
if (n.length() == 0) {
cout << "string accepted" << endl;
} else {
if (n[0] == 'a' ) {
stateAB(n.substr(1));
} else if (n[0] == 'b' ) {
stateA(n.substr(1));
}
}
}
int main() {
string n;
cin >> n;
stateA(n);
return 0;
}
|
Java
import java.util.Scanner;
public class StateMachine {
static void stateA(String n) {
if (n.length() == 0 ) {
System.out.println( "string not accepted" );
} else {
if (n.charAt( 0 ) == 'a' ) {
stateAB(n.substring( 1 ));
} else if (n.charAt( 0 ) == 'b' ) {
stateA(n.substring( 1 ));
}
}
}
static void stateAB(String n) {
if (n.length() == 0 ) {
System.out.println( "string not accepted" );
} else {
if (n.charAt( 0 ) == 'a' ) {
stateABC(n.substring( 1 ));
} else if (n.charAt( 0 ) == 'b' ) {
stateAC(n.substring( 1 ));
}
}
}
static void stateABC(String n) {
if (n.length() == 0 ) {
System.out.println( "string accepted" );
} else {
if (n.charAt( 0 ) == 'a' ) {
stateABC(n.substring( 1 ));
} else if (n.charAt( 0 ) == 'b' ) {
stateAC(n.substring( 1 ));
}
}
}
static void stateAC(String n) {
if (n.length() == 0 ) {
System.out.println( "string accepted" );
} else {
if (n.charAt( 0 ) == 'a' ) {
stateAB(n.substring( 1 ));
} else if (n.charAt( 0 ) == 'b' ) {
stateA(n.substring( 1 ));
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print( "Enter the string: " );
if (scanner.hasNext()) {
String n = scanner.next();
stateA(n);
} else {
System.out.println( "No input provided." );
}
scanner.close();
}
}
|
Python3
def stateA(n):
if ( len (n) = = 0 ):
print ("string not accepted")
else :
if (n[ 0 ] = = 'a' ):
stateAB(n[ 1 :])
elif (n[ 0 ] = = 'b' ):
stateA(n[ 1 :])
def stateAB(n):
if ( len (n) = = 0 ):
print ("string not accepted")
else :
if (n[ 0 ] = = 'a' ):
stateABC(n[ 1 :])
elif (n[ 0 ] = = 'b' ):
stateAC(n[ 1 :])
def stateABC(n):
if ( len (n) = = 0 ):
print ("string accepted")
else :
if (n[ 0 ] = = 'a' ):
stateABC(n[ 1 :])
elif (n[ 0 ] = = 'b' ):
stateAC(n[ 1 :])
def stateAC(n):
if ( len (n) = = 0 ):
print ("string accepted")
else :
if (n[ 0 ] = = 'a' ):
stateAB(n[ 1 :])
elif (n[ 0 ] = = 'b' ):
stateA(n[ 1 :])
n = input ()
stateA(n)
|
C#
using System;
class StateMachine
{
static void StateA( string n);
static void StateAB( string n);
static void StateABC( string n);
static void StateAC( string n);
static void StateA( string n)
{
if ( string .IsNullOrEmpty(n))
{
Console.WriteLine( "Invalid input: string not accepted" );
return ;
}
if (n[0] == 'a' )
{
StateAB(n.Substring(1));
}
else if (n[0] == 'b' )
{
StateA(n.Substring(1));
}
}
static void StateAB( string n)
{
if ( string .IsNullOrEmpty(n))
{
Console.WriteLine( "Invalid input: string not accepted" );
return ;
}
if (n[0] == 'a' )
{
StateABC(n.Substring(1));
}
else if (n[0] == 'b' )
{
StateAC(n.Substring(1));
}
}
static void StateABC( string n)
{
if ( string .IsNullOrEmpty(n))
{
Console.WriteLine( "string accepted" );
return ;
}
if (n[0] == 'a' )
{
StateABC(n.Substring(1));
}
else if (n[0] == 'b' )
{
StateAC(n.Substring(1));
}
}
static void StateAC( string n)
{
if ( string .IsNullOrEmpty(n))
{
Console.WriteLine( "string accepted" );
return ;
}
if (n[0] == 'a' )
{
StateAB(n.Substring(1));
}
else if (n[0] == 'b' )
{
StateA(n.Substring(1));
}
}
static void Main()
{
Console.Write( "Enter a string: " );
string n = Console.ReadLine();
StateA(n);
}
}
|
Javascript
function stateA(n) {
if (n.length === 0) {
console.log( "String not accepted" );
} else {
if (n[0] === 'a' ) {
stateAB(n.substr(1));
} else if (n[0] === 'b' ) {
stateA(n.substr(1));
}
}
}
function stateAB(n) {
if (n.length === 0) {
console.log( "String not accepted" );
} else {
if (n[0] === 'a' ) {
stateABC(n.substr(1));
} else if (n[0] === 'b' ) {
stateAC(n.substr(1));
}
}
}
function stateABC(n) {
if (n.length === 0) {
console.log( "String accepted" );
} else {
if (n[0] === 'a' ) {
stateABC(n.substr(1));
} else if (n[0] === 'b' ) {
stateAC(n.substr(1));
}
}
}
function stateAC(n) {
if (n.length === 0) {
console.log( "String accepted" );
} else {
if (n[0] === 'a' ) {
stateAB(n.substr(1));
} else if (n[0] === 'b' ) {
stateA(n.substr(1));
}
}
}
let inputString = prompt( "Enter a string: " );
stateA(inputString);
|
Output
Input: aaab
Output: string accepted
Input: baba
Output: string not accepted
Frequently Asked Questions
Q.1: Why is it required to develop a non-deterministic finite automaton (NFA) before building a DFA for this problem?
Answer:
For languages with complex patterns, designing an NFA first simplifies DFA construction. NFAs make language properties easier to visualize and work with by providing more flexibility. The translation from NFA to DFA ensures determinism and organizes problem-solving.
Q.2: Can this method work for languages with more sophisticated patterns and conditions?
Answer:
Yes, languages with more complex patterns and circumstances can use this NFA-to-DFA method. It breaks down the challenge into small steps and gives a systematic DFA for such languages. As language complexity develops, state transition tables and the DFA may grow and require careful design.
Conclusion
Non-deterministic finite automata (NFA) simplifies building deterministic finite automata (DFA) for languages with specified patterns, such as strings with the 2nd symbol from the right being ‘a’. This method simplifies and organizes DFA construction. Automata theory benefits from this method for representing and processing complex linguistic patterns.