DFA Construction for Even # of 0s and Odd # of 1s over {0,1}\{0,1\}

DFA Construction for Even # of 0s and Odd # of 1s over {0,1}\{0,1\}

Verified Sources
Nov 4, 2026

We want a deterministic finite automaton (DFA) over Σ={0,1}\Sigma=\{0,1\} that accepts exactly those strings that contain:

  • an even number of 0s, and
  • an odd number of 1s.

A standard approach is to build a product-parity automaton that tracks two parities simultaneously: parity of the number of 0s, and parity of the number of 1s.

We represent each state as a pair: state=(p0,p1)\text{state} = (p_0, p_1) where p0∈{even,odd}p_0\in\{\text{even},\text{odd}\} is the parity of the number of 0s read so far, and p1∈{even,odd}p_1\in\{\text{even},\text{odd}\} is the parity of the number of 1s read so far. The DFA starts at (even,even)(\text{even},\text{even}) because the empty string has 0 zeros (even) and 0 ones (even). It accepts when (p0,p1)=(even,odd)(p_0,p_1)=(\text{even},\text{odd}).

Mermaid view of the core idea:

Key terms:

  • DFA
  • Alphabet
  • Accepting state
  • Transition function

Building DFA for Even/Odd Parity (Conceptual)

DFA definition (explicit construction)

We define the DFA M=(Q,Σ,δ,q0,F)M=(Q,\Sigma,\delta,q_0,F) as follows.

  • State set:
    Q={qee,qeo,qoe,qoo}Q=\{q_{ee}, q_{eo}, q_{oe}, q_{oo}\} where qabq_{ab} means:

    • aa = parity of # of 0s so far (e=even, o=odd)
    • bb = parity of # of 1s so far (e=even, o=odd)
  • Alphabet:
    Σ={0,1}\Sigma=\{0,1\}

  • Start state:
    q0=qeeq_0=q_{ee}

  • Accepting set:
    F={qeo}F=\{q_{eo}\}
    because we need even number of 0s and odd number of 1s.

  • Transition function:
    Reading a symbol flips the parity of the corresponding count:

    • On input 00: toggle parity of # of 0s, leave # of 1s parity unchanged.
    • On input 11: toggle parity of # of 1s, leave # of 0s parity unchanged.

Construct the transition table from the parity rules

  1. 1
    Step 1

    Create four states q_ee, q_eo, q_oe, q_oo representing (parity of #0s, parity of #1s).

  2. 2
    Step 2

    On reading 0, swap the first component e<->o while keeping the second component fixed.

  3. 3
    Step 3

    On reading 1, swap the second component e<->o while keeping the first component fixed.

  4. 4
    Step 4

    Compute δ(q,s) for each state q and symbol s∈{0,1} using the toggles.

  5. 5
    Step 5

    Set F={q_eo} because acceptance requires even #0s and odd #1s.

Transition table

Let δ(q,s)\delta(q,s) be the next state.

Current stateOn input 0On input 1
qeeq_{ee}qoeq_{oe}qeoq_{eo}
qeoq_{eo}qooq_{oo}qeeq_{ee}
qoeq_{oe}qeeq_{ee}qooq_{oo}
qooq_{oo}qeoq_{eo}qoeq_{oe}

This follows directly from parity toggling:

  • 00 flips “#0s parity”
  • 11 flips “#1s parity”

Pro Tip

When you see “even/odd number of symbols,” think in terms of parity bits. A DFA for kk independent parity constraints typically needs 2k2^k states; here k=2k=2, so 4 states.

Common mistake

Do not accept based on just one parity condition. This language requires BOTH: even number of 0s AND odd number of 1s.

Verification: trace accepted vs. rejected strings

We verify using representative strings by counting 0s and 1s and/or simulating the DFA by state transitions.

Strings that should be accepted (even #0s, odd #1s)

We must have:

  • #0s = even (0,2,4,...)
  • #1s = odd (1,3,5,...)
  1. Input: 1
  • #0s = 0 (even), #1s = 1 (odd) → accept
  • DFA trace:
    qee→1qeoq_{ee} \xrightarrow{1} q_{eo} (accepting)
  1. Input: 001
  • #0s = 2 (even), #1s = 1 (odd) → accept
  • DFA trace:
    qee→0qoe→0qee→1qeoq_{ee}\xrightarrow{0}q_{oe}\xrightarrow{0}q_{ee}\xrightarrow{1}q_{eo} (accept)
  1. Input: 10101
  • #0s = 2 (even), #1s = 3 (odd) → accept
  1. Input: 000111
  • #0s = 3 (odd) actually this one would be rejected (included here as a contrast).
    So we instead use: Input: 00111
    • #0s = 2 (even), #1s = 3 (odd) → accept

Strings that should be rejected (violates at least one parity condition)

  1. Input: 0
  • #0s = 1 (odd), #1s = 0 (even) → reject
  • DFA trace:
    qee→0qoeq_{ee}\xrightarrow{0}q_{oe} (not accepting)
  1. Input: 11
  • #0s = 0 (even), #1s = 2 (even) → reject
  • DFA trace:
    qee→1qeo→1qeeq_{ee}\xrightarrow{1}q_{eo}\xrightarrow{1}q_{ee} (back to non-accepting)
  1. Input: 010
  • #0s = 2 (even), #1s = 1 (odd) → actually accept (use as a positive check)
  • Therefore for rejection use 0110:
    • 0110 has #0s=2 (even), #1s=2 (even) → reject
  1. Input: empty string ε
  • #0s=0 (even), #1s=0 (even) → needs odd #1s, so reject
  • DFA trace: start at qeeq_{ee} which is non-accepting.

How the DFA enforces both parity conditions

Initial parities

Start

Begin in qeeq_{ee} (0 zeros even, 0 ones even)."

Update #0 parity

Reading 0

Toggle the first component (e↔o) to reflect the new count of zeros."

Update #1 parity

Reading 1

Toggle the second component (e↔o) to reflect the new count of ones."

Check acceptance

End of input

Accept iff the final state is qeoq_{eo}."

Quick state interpretation example

Consider input 001:

  • Start: qeeq_{ee}.
  • Read 0: qee→qoeq_{ee}\to q_{oe} (odd zeros, even ones).
  • Read 0: qoe→qeeq_{oe}\to q_{ee} (even zeros, even ones).
  • Read 1: qee→qeoq_{ee}\to q_{eo} (even zeros, odd ones) → accept.

This demonstrates the DFA’s correctness mechanism: it never “counts” unboundedly; it only tracks parity.

Additional checks and edge cases

Knowledge Check

Question 1 of 4
Q1Single choice

Which state(s) should be accepting in the DFA for even number of 0s and odd number of 1s?