Repository: TheAlgorithms/Java
File: src/main/java/com/thealgorithms/strings/AhoCorasick.java (Java)

Code before:
                    // Calculate the suffix link for the child based on the parent's suffix link
                    while (!parentSuffix.getChild().containsKey(cc) && parentSuffix != root) {
                        parentSuffix = parentSuffix.getSuffixLink();
                    }

                    // Set the calculated suffix link or default to root
                    if (parentSuffix.getChild().containsKey(cc)) {
                        currentChild.setSuffixLink(parentSuffix.getChild().get(cc));
                    } else {
                        currentChild.setSuffixLink(root);
                    }

                    q.add(currentChild); // Add the child node to the queue for further processing
                }

                // Establish output links for nodes to efficiently identify patterns within patterns
                if (currentState.getSuffixLink().getPatternInd() >= 0) {
                    currentState.setOutputLink(currentState.getSuffixLink());
                } else {
                    currentState.setOutputLink(currentState.getSuffixLink().getOutputLink());
                }
            }
        }

        // Searches for patterns in the input text and records their positions
        public ArrayList<ArrayList<Integer>> searchIn(String text) {
            /*
             * positionByStringIndexValue is the list of list containing the indexes of words in patterns/dictionary
             * list index represents word.
             * eg - list[0] contains the list of start-index of word pattern[0]
             *      list[1] contains the list of start-index of word pattern[1]
             *      ......
             *      ......
             *      list[n] contains the list of start-index of word pattern[n]
             */
            ArrayList<ArrayList<Integer>> positionByStringIndexValue = new ArrayList<>(patterns.length); // Stores positions where patterns are found in the text
            Node parent = root; // Start searching from the root node

            for (int i = 0; i < patterns.length; i++) {
                positionByStringIndexValue.add(new ArrayList<Integer>()); // Initialize a list to store positions of the current pattern
            }

            for (int i = 0; i < text.length(); i++) {
                char ch = text.charAt(i); // Get the current character in the text

                // Check if the current node has a child for the current character
                if (parent.getChild().containsKey(ch)) {
                    parent = parent.getChild().get(ch); // Update the current node to the child node

                    // If the current node represents a pattern, record its position in positionByStringIndexValue
                    if (parent.getPatternInd() > -1) {

Review comment (suggestion):
```suggestion
        public ArrayList<ArrayList<Integer>> searchIn(final String text) {

```

Code after:
                    Node parentSuffix = currentState.getSuffixLink(); // Get the parent's suffix link

                    // Calculate the suffix link for the child based on the parent's suffix link
                    while (!parentSuffix.getChild().containsKey(cc) && parentSuffix != root) {
                        parentSuffix = parentSuffix.getSuffixLink();
                    }

                    // Set the calculated suffix link or default to root
                    if (parentSuffix.getChild().containsKey(cc)) {
                        currentChild.setSuffixLink(parentSuffix.getChild().get(cc));
                    } else {
                        currentChild.setSuffixLink(root);
                    }

                    q.add(currentChild); // Add the child node to the queue for further processing
                }

                // Establish output links for nodes to efficiently identify patterns within patterns
                if (currentState.getSuffixLink().getPatternInd() >= 0) {
                    currentState.setOutputLink(currentState.getSuffixLink());
                } else {
                    currentState.setOutputLink(currentState.getSuffixLink().getOutputLink());
                }
            }
        }

        private ArrayList<ArrayList<Integer>> initializePositionByStringIndexValue() {
            ArrayList<ArrayList<Integer>> positionByStringIndexValue = new ArrayList<>(patterns.length); // Stores positions where patterns are found in the text
            for (int i = 0; i < patterns.length; i++) {
                positionByStringIndexValue.add(new ArrayList<Integer>());
            }
            return positionByStringIndexValue;
        }

        // Searches for patterns in the input text and records their positions
        public ArrayList<ArrayList<Integer>> searchIn(final String text) {
            var positionByStringIndexValue = initializePositionByStringIndexValue(); // Initialize a list to store positions of the current pattern
            Node parent = root; // Start searching from the root node

            PatternPositionRecorder positionRecorder = new PatternPositionRecorder(positionByStringIndexValue);

            for (int i = 0; i < text.length(); i++) {
                char ch = text.charAt(i); // Get the current character in the text

                // Check if the current node has a child for the current character
                if (parent.getChild().containsKey(ch)) {
                    parent = parent.getChild().get(ch); // Update the current node to the child node
                    positionRecorder.recordPatternPositions(parent, i); // Use the method in PatternPositionRecorder to record positions
                } else {
                    // If no child node exists for the character, backtrack using suffix links
                    while (parent != root && !parent.getChild().containsKey(ch)) {