# Aho-Corasick algorithm

The Aho-Corasick algorithm is a string searching algorithm created by Alfred V. Aho and Margaret J. Corasick. It is a kind of dictionary-matching algorithm that locates elements of a finite set of strings (the "dictionary") within an input text. It matches all patterns "at once", so the complexity of the algorithm is linear in the length of the patterns plus the length of the searched text plus the number of output matches. Note that because all matches are found, there can be a quadratic number of matches if every substring matches (e.g. dictionary = `a, aa, aaa, aaaa` and input string is `aaaa`).

Informally, the algorithm constructs a trie with suffix tree-like set of links from each node representing a string (e.g. `abc`) to the node corresponding to the longest proper suffix (e.g. `bc` if it exists, else `c` if that exists, else the root). It also contains links from each node to the longest suffix node that corresponds to a dictionary entry; thus all of the matches may be enumerated by following the resulting linked list. It then uses the trie at runtime, moving along the input and keeping the longest match, using the suffix links to make sure that computation is linear. For every node that is in the dictionary and every link along the dictionary suffix linked list, an output is generated.

When the pattern dictionary is known in advance (e.g. a computer virus database), the construction of the automaton can be performed once off-line and the compiled automaton stored for later use. In this case, its run time is linear in the length of the input plus the number of matched entries.

The Aho-Corasick algorithm formed the basis of the original Unix command fgrep.

The following is the Aho-Corasick data structure constructed from the specified dictionary, with each row in the table representing a node in the trie, with the column path indicating the (unique) sequence of characters from the root to the node.

Dictionary { a, ab, bc, bca, c, caa }
() -
(a) + ()
(ab) + (b)
(b) - ()
(bc) + (c) (c)
(bca) + (ca) (a)
(c) + ()
(ca) - (a) (a)
(caa) + (a) (a)

At each step, the current node is extended by finding its daughter, and if that doesn't exist, finding its suffix's daughter, and if that doesn't work, finding its suffix's suffix's daughter, finally ending in the root node if nothing's seen before.

Execution on input string abccab yields the following steps:

Analysis of input string `abccab`
Node Remaining String Output:End Position Transition Output
() abccab   start at root
(a) bccab a:1 () to daughter (a) Current node
(ab) ccab ab:2 (a) to daughter (ab) Current node
(bc) cab bc:3, c:3 (ab) to suffix (b) to daughter (bc) Current Node, Dict suffix node
(c) ab c:4 (bc) to suffix (c) to suffix () to daughter (c) Current node
(ca) b a:5 (c) to daughter (ca) Dict suffix node
(ab)   ab:6 (ca) to suffix (a) to daughter (ab) Current node

In general, more than one dictionary suffix link may need to be followed, as more than one dictionary entry may end at a given character in the input.

## Sources

• Aho, Alfred V.; Margaret J. Corasick (June 1975). "Efficient string matching: An aid to bibliographic search". Communications of the ACM 18 (6): 333–340. doi:10.1145/360825.360855.  (Access to the full text may be restricted.)