Next: Building the DFA, Previous: What is a DFA, Up: DFA
Recognizing with a DFA is very simple
and thus very fast
(See 'scan_for_pattern()
' in the 'engine/matchpat.c' file).
Starting from the start state, we only need to read the board following the spiral path, jump from states to states following the transitions labelled by the values read on the board and collect the patterns indexes on the way. If we reach the error state (zero), it means that no more patterns will be matched. The worst case complexity of this algorithm is o(m) where m is the size of the biggest pattern.
Here is an example of scan:
First we build a minimal DFA recognizing these patterns: "X..X", "X???", "X.OX" and "X?oX". Note that wildcards like '?','o', or 'x' give multiple out-transitions.
---------------------------------------------------- state | . | O | X | # | att ---------------------------------------------------- 1 | 0 | 0 | 2 | 0 | 2 | 3 | 10 | 10 | 0 | 3 | 4 | 7 | 9 | 0 | 4 | 5 | 5 | 6 | 0 | 5 | 0 | 0 | 0 | 0 | 2 6 | 0 | 0 | 0 | 0 | 4 2 1 7 | 5 | 5 | 8 | 0 | 8 | 0 | 0 | 0 | 0 | 4 2 3 9 | 5 | 5 | 5 | 0 | 10 | 11 | 11 | 9 | 0 | 11 | 5 | 5 | 12 | 0 | 12 | 0 | 0 | 0 | 0 | 4 2 ----------------------------------------------------
We perform the scan of the string "X..XXO...." starting from state 1:
Current state: 1, substring to scan : X..XXO....
We read an 'X' value, so from state 1 we must go to state 2.
Current state: 2, substring to scan : ..XXO....
We read a '.' value, so from state 2 we must go to state 3 and so on ...
Current state: 3, substring to scan : .XXO.... Current state: 4, substring to scan : XXO.... Current state: 6, substring to scan : XO.... Found pattern 4 Found pattern 2 Found pattern 1
After reaching state 6 where we match patterns 1,2 and 4, there is no out-transitions so we stop the matching. To keep the same match order as in the standard algorithm, the patterns indexes are collected in an array and sorted by indexes.