Search code examples
javastringrecursionreverse

Reverse the words in a sentence but not punctuation using recursion


How to reverse the words in a sentence, but not punctuation using recursion. The sentence is said to use punctuation marks: ,.?!

Input: "Jack, come home!"

Output: "home, come Jack!"

Now I have somehow managed to complete the task correctly but without using recursion. How should I convert this work to use recursion to solve the problem?

Here's the method:

public static StringBuilder reverseSentenceWithPunctuation(String sentence, int i) {
        String[] parts = sentence.split(" ");
        StringBuilder newSentence = new StringBuilder();
        Map<Integer, Character> punctuationMap = new HashMap<>();

        for (int j = 0; j < parts.length; j++) {
            if (parts[j].endsWith(",") || parts[j].endsWith(".") || parts[j].endsWith("!") || parts[j].endsWith("?")) {
                char lastSymbol = parts[j].charAt(parts[j].length()-1);
                punctuationMap.put(j, lastSymbol);
                String changedWord = parts[j].replace(String.valueOf(lastSymbol), "");
                parts[j] = changedWord;
            }
        }

        for (int j = parts.length-1; j >= 0; j--) {
            newSentence.append(parts[j]);
            if (punctuationMap.containsKey(i)) {
                newSentence.append(punctuationMap.get(i));
                newSentence.append(" ");
            } else
                newSentence.append(" ");
            i++;
        }
        return newSentence;
    }

Thanks in advance!


Solution

  • To implement this task using recursion, a pattern matching the first and the last words followed by some delimiters should be prepared:

    word1 del1 word2 del2 .... wordLast delLast
    

    In case of matching the input the result is calculated as:

    wordLast del1 REVERT(middle_part) + word1 delLast
    

    Example implementation may be as follows (the words are considered to contain English letters and apostrophe ' for contractions):

    static Pattern SENTENCE = Pattern.compile("^([A-Za-z']+)([^A-Za-z]+)?(.*)([^'A-Za-z]+)([A-Za-z']+)([^'A-Za-z]+)?$");
    
    public static String revertSentence(String sentence) {
        
        Matcher m = SENTENCE.matcher(sentence);
        if (m.matches()) {
            return m.group(5) + (m.group(2) == null ? "" : m.group(2)) 
                + revertSentence(m.group(3) + m.group(4)) // middle part
                + m.group(1) + (m.group(6) == null ? "" : m.group(6));
        }
        return sentence;
    }
    

    Tests:

    System.out.println(revertSentence("Jack, come home!"));
    System.out.println(revertSentence("Jack, come home please!!"));
    System.out.println(revertSentence("Jane cried: Will you come home Jack, please, don't go!"));
    

    Output:

    home, come Jack!
    please, home come Jack!!
    go don't: please Jack home come you, Will, cried Jane!