Untitled

 avatar
unknown
java
2 years ago
2.6 kB
2
Indexable
import java.util.*;

public class NFA {
    private int statesCount;
    private Set<Integer> finalStates;
    private Map<Character, List<Integer>>[] transitions;

    public NFA(String regex) {
        finalStates = new HashSet<>();
        // Построение НКА по регулярному выражению
        // ...
    }

    // Добавление перехода
    private void addTransition(int state, char symbol, int nextState) {
        if (transitions[state] == null) {
            transitions[state] = new HashMap<>();
        }
        if (!transitions[state].containsKey(symbol)) {
            transitions[state].put(symbol, new ArrayList<>());
        }
        transitions[state].get(symbol).add(nextState);
    }

    // Получение множества состояний, достижимых из данного множества по символу
    private Set<Integer> move(Set<Integer> states, char symbol) {
        Set<Integer> nextStates = new HashSet<>();
        for (int state : states) {
            if (transitions[state] != null && transitions[state].containsKey(symbol)) {
                nextStates.addAll(transitions[state].get(symbol));
            }
        }
        return nextStates;
    }

    // Получение множества состояний, достижимых из данного множества по эпсилон-переходу
    private Set<Integer> epsilonClosure(Set<Integer> states) {
        Set<Integer> closure = new HashSet<>(states);
        Queue<Integer> queue = new LinkedList<>(states);
        while (!queue.isEmpty()) {
            int state = queue.poll();
            if (transitions[state] != null && transitions[state].containsKey(null)) {
                for (int nextState : transitions[state].get(null)) {
                    if (!closure.contains(nextState)) {
                        closure.add(nextState);
                        queue.offer(nextState);
                    }
                }
            }
        }
        return closure;
    }

    // Проверка, принадлежит ли данная строка языку, задаваемому НКА
    public boolean accepts(String str) {
        Set<Integer> currentStates = epsilonClosure(Collections.singleton(0));
        for (char symbol : str.toCharArray()) {
            currentStates = epsilonClosure(move(currentStates, symbol));
        }
        return !Collections.disjoint(currentStates, finalStates);
    }
}