Более теоретический ответ:
Детерминированные конечные автоматы имеют взаимно однозначное соответствие с регулярными выражениями;то есть для каждого обычного языка вы можете создать DFA, который будет принимать именно те строки, которые содержатся в обычном языке.И для каждого обычного языка вы можете создать регулярное выражение, которое будет соответствовать только строкам на этом языке.Таким образом, для любого регулярного выражения можно создать DFA, который принимает точно такие же строки, и наоборот.
Недетерминированный конечный автомат (NFA) можно превратить в детерминированный конечный автомат (DFA) с помощьюпостроение состояния DFA для каждой комбинации состояний в NFA.(Это | Q | 2 состояний, что является конечным числом.)
С этим знанием мы можем обратить DFA A
и создать DFA A'
, который принимает каждыйстрока, которую A
отклоняет, и отклоняет каждую строку, которую A
принимает.
Это можно сделать, превратив все конечные состояния во временные начальные состояния, а начальное состояние - в конечное состояние.Затем мы добавляем epsilon-переходы из нового начального состояния в каждое из этих временных начальных состояний, чтобы сделать его действительным NFA (epsilon-NFA, если вы хотите придираться).Затем мы превращаем его в DFA, поскольку мы знаем, что можем это сделать.
Единственный оставшийся шаг - превратить наш новый DFA в регулярное выражение.Алгоритм для этого глупо прост: для каждого пути от начального до конечного состояний мы включаем его в регулярное выражение, используя |
(или) для каждой ветви, конкатенацию для последовательных состояний и *
(закрытие клины) длякаждый цикл.