Introduction
A deterministic finite automaton (DFA) is a finite-state machine that reads an input string from left to right, one symbol at a time, and either accepts or rejects. At every step the next state is uniquely determined by the current state and the current symbol. DFAs recognize exactly the regular languages.
The working skills are designing a DFA for a stated language, simulating a given DFA on a string, counting states, and reasoning about what language a transition diagram accepts. This note fixes the formal definition, the extended transition function, design patterns and two fully checked examples: binary integers divisible by 3, and strings ending with 01.
Prerequisites
- Alphabets, Strings and Languages: strings, , languages.
Core concepts
Formal definition
A DFA is a 5-tuple where:
- is a finite nonempty set of states.
- is the input alphabet.
- is the transition function (total: defined for every state and symbol).
- is the start state.
- is the set of accepting (final) states.
Deterministic and total. From each state, for each symbol, there is exactly one next state. An incomplete diagram is conventionally read as having a missing dead (sink) state that rejects and stays on every symbol; state it when you add one.
How a DFA processes a string
The transition function extends to strings by :
The DFA accepts iff . The language of is
Acceptance depends only on the state after reading all of . There is no stack and no unbounded memory: the current state is the entire memory.
Transition diagrams and tables
- States are circles; accepting states have a double circle.
- The start state has an incoming arrow with no source.
- An edge means . Multiple symbols on one edge mean several transitions drawn together.
- A transition table has rows = states, columns = symbols, entries = . Mark the start and the accepting rows.
Dead states and unreachable states
- A dead (reject sink) state satisfies for every . Irreversible rejection can be represented by one dead sink; all hopeless states collapse to that sink on minimization.
- An unreachable state is never entered from on any string. It does not affect and can be removed.
How it works
Design patterns
- Track a property of the prefix read so far that is finite-valued: length modulo , value modulo , progress toward a keyword, parity of a count, last few symbols.
- Make one state per possible value of that property.
- Mark accepting those values that mean "the string so far is in the language".
- Fill every transition; add a dead state if the property can fail permanently.
Keyword / suffix pattern. For "strings ending with " where , keep the longest prefix of that is a suffix of the text read so far (the failure function idea from string matching). That needs at most states.
Modular arithmetic. For binary strings whose integer value is , states are residues . Reading bit sends residue to .
Algorithms and pseudocode
Pseudocode uses sets and maps; is the next state.
DFA-ACCEPT(M, w)
1 q <- M.q0
2 for each symbol a in w, left to right
3 q <- M.delta[q][a]
4 return q in M.FTime ; space beyond the machine description.
DFA-LANGUAGE-NONEMPTY(M)
1 reach <- {M.q0}; work <- queue with M.q0
2 while work is not empty
3 p <- dequeue(work)
4 for each a in Sigma
5 r <- M.delta[p][a]
6 if r not in reach
7 add r to reach; enqueue r
8 return reach intersects M.FEmptiness of a DFA language is decidable in linear time in the size of the machine (reachability).
Mathematical explanation
Myhill-Nerode (statement for design intuition)
Define iff for every , . The equivalence classes of are exactly the distinctions a DFA for must remember. is regular iff has finitely many classes, and the minimal DFA has one state per class (see DFA Minimization).
Closure teaser
If and are DFA languages, so are , and , by product constructions and flipping accepting states. Full proofs sit in Closure and Decision Properties of Regular Languages.
Worked examples
Example 1: binary value divisible by 3
Alphabet . Interpret as a binary integer ( has value 0). States remember the value of the prefix modulo 3. Start and only accept: .
| State | on 0 | on 1 |
|---|---|---|
Traces:
0: value 0, stay in , accept.1: value 1, to , reject.11: value 3, , accept.10: value 2, to , reject.
Induction on the length shows that after reading the machine is in with , because appending bit maps the value to .

Example 2: strings ending with 01
States remember the current progress toward the suffix 01:
| State | Meaning | Accept? |
|---|---|---|
| no progress | no | |
0 | suffix is 0 | no |
01 | suffix is 01 | yes |
1 | suffix is 1 (but not 01) | no |
Transitions for a redundant four-state refinement of the canonical three-state suffix-progress automaton (the states labelled epsilon and 1 have equivalent future behaviour):
| 0 | 1 | |
|---|---|---|
0 | 1 | |
0 | 0 | 01 |
01 | 0 | 1 |
1 | 0 | 1 |
Check: 01 accepted; 001 accepted; 010 rejected; 1 rejected; every string of length at most 7 behaves as the predicate "ends with 01".
This DFA is correct but not minimal. States and 1 behave identically: both go to 0 on 0 and to 1 on 1, and both reject. Merging them leaves 3 states, which is the minimum: the prefixes , 0, 01 are pairwise distinguishable ( and 0 by the continuation 1; either of them and 01 by the empty continuation). In general "ends with ", , needs exactly states.
Example 3: strings containing the substring aba
Alphabet . State means "the longest suffix of the input that is a prefix of aba has length "; state 3 means aba has already occurred, and it is an accepting sink.
| State | on a | on b | Accept? |
|---|---|---|---|
| 0 | 1 | 0 | no |
| 1 | 1 | 2 | no |
| 2 | 3 | 0 | no |
| 3 | 3 | 3 | yes |
The two failure edges decide the question. From state 1 on a the machine stays in 1 (the new a can start the pattern again), and from state 2 on b it returns to 0 (abb has no suffix that begins aba). Traces: abaa ends in 3 and is accepted; abba passes 1, 2, 0, 1 and is rejected; aababb reaches 3 at the fourth symbol and stays there. The four prefixes , a, ab, aba are pairwise distinguishable, so 4 states is minimal.
Substring versus suffix. "Contains " has an accepting sink; "ends with " does not, because later symbols can destroy the match. Both need states. "Starts with " needs : the progress states plus a dead state for an early mismatch.
Example 4: two counters at once
Let . Track the pair : 6 states, start and only accept ; a flips the first component, b adds 1 to the second modulo 3. No two pairs are equivalent (pairs differing in the -parity are separated by a suitable string of s followed by nothing or by a, and similarly for the -count), so the minimal DFA has exactly states. The same 6 states with accept set "first component 0 or second component 0" recognize the union, which also needs 6 states.
Example 5: counting DFAs
How many DFAs are there with the two states , start state , over ? Each of the table entries has 2 choices and is any of the 4 subsets: . In general, with labelled states, a fixed start state and ,
How many of the 64 accept ? Exactly those with no reachable accepting state. : all 16 tables. : must be unreachable, so both edges of loop on , while 's two edges are free: 4 tables. containing always accepts . Total . These 64 machines accept only 26 different languages, a reminder that counting machines is not counting languages.
Important properties and observations
- A DFA has exactly one run on each string; acceptance is "final state in ".
- Adding unreachable states does not change the language; removing a dead state may make partial (avoid in formal answers unless the problem allows incomplete DFAs).
- Number of states is not unique for a language unless the DFA is minimal.
- iff every reachable state is accepting; iff no accepting state is reachable.
- DFAs and NFAs define the same class of languages; DFAs can need exponentially more states (see NFA and Subset Construction).
Minimal state counts to remember
Over unless stated. Every count is for a complete minimal DFA, so a dead state is included when one is needed.
| Language | Minimal states | Why |
|---|---|---|
| lengths , plus dead for "too long" | ||
| same states, different accept set | ||
| lengths , then an accepting sink | ||
| residues of the length | ||
| residues of the count | ||
| and | product; the same for "or" when and , ; trivial moduli can collapse the OR language | |
| ends with , | prefixes of , no sink | |
| contains , | prefixes of , accepting sink | |
| starts with nonempty , | prefixes of , accepting sink, dead state | |
| first and last symbols equal (nonempty) | 5 | start, and two states for each first symbol |
| -th symbol from the end is | must remember the last symbols | |
| binary value divisible by , odd | the factor only needs the last bits |
For starts-with, the empty prefix gives the universal language and needs one state.
The last row needs care. Divisibility by 3 needs 3 states, but divisibility by 4 needs only 3 (not 4): after padding with leading zeros, a number is a multiple of 4 iff its last two bits are 00. Thus accept epsilon and 0 as well as every string ending 00. The initial state is accepting; the three state classes are "epsilon, 0, or ends 00", "ends 10", and "ends 1". Divisibility by 6 needs , by 8 needs 4, by 12 needs 5, by 16 needs 5. These counts treat as the value 0 and allow leading zeros; a question that forbids leading zeros adds states, so read it carefully.
Acceptance of the empty string. iff . Use this as a one-second sanity check on every designed machine.
Complement needs a complete DFA. Swapping and recognizes only when is total. On a partial diagram, first add the dead state; it then becomes accepting in the complement.
Common misconceptions.
- "Missing transitions mean reject immediately." Formally is total; model missing arrows by a dead state.
- "The machine accepts as soon as it visits an accept state." No: acceptance is checked only after the whole string is read (unless the problem explicitly asks for acceptance on a prefix).
- "More states always mean a larger language." False; state count is about memory, not language size.
GATE examination perspective
- SIMULATE CAREFULLY. Write the state after each symbol; do not skip.
- MODULO MACHINES. Confirm the update rule for binary value; for decimal digits use .
- SUFFIX LANGUAGES. Build the progress automaton; follow the particular table given: its redundant refinement sends
01on1to1, which is equivalent to in the canonical minimized automaton. - COUNT THE STATES. Minimal state counts use Myhill-Nerode distinguishability: exhibit prefixes that are pairwise distinguishable for the lower bound and an -state DFA for the upper bound. Use the table of minimal counts above, and recheck the dead state.
- "MINIMAL" WITH A DEAD STATE. Some questions count the dead state and some say "ignore the trap state". The table counts it; subtract 1 only when the question says so.
- BINARY DIVISIBILITY. Divisible by needs states, not . Decimal digits use .
- COUNTING MACHINES. "How many DFAs with states" counts tables and accept sets ( with a fixed start), not languages.
- CONTAINS VERSUS ENDS WITH. Check whether the accept state is a sink. A sink is right for "contains", wrong for "ends with".
- DEAD STATE. If the question's diagram omits transitions, say that a dead sink is assumed.
Summary
Sources
- J. E. Hopcroft, R. Motwani, J. D. Ullman, Introduction to Automata Theory, Languages, and Computation, 3rd ed., Pearson Addison-Wesley: Section 2.2 (deterministic finite automata), Section 2.4 (text search), Section 4.4 (equivalence and minimization).
- M. Sipser, Introduction to the Theory of Computation, 3rd ed., Cengage Learning: Section 1.1 (finite automata, designing finite automata).
- P. Linz, An Introduction to Formal Languages and Automata, 6th ed., Jones & Bartlett Learning: Section 2.1 (deterministic finite accepters).