Inverting letters in words per line

I have encoded the following solution and it works, except when there is punctuation. I was wondering if there is a complexity of complexity O (1) and O (string length), without using the reverse () method or anything like that, which makes this task too easy. Any answer that can also handle punctuation correctly would be great.

Example:

This line: "I love chocolate"

The returned string should be: "I evol etalocohc"

For clarity, when I speak of punctuation correctly, I mean that punctuation should not move.

 // reverse the letters of every word in a sentence (string), and return the result

 public static String reverse(String x)
 {
     String[] str = x.split(" ");

     StringBuilder rev = new StringBuilder("");

     for (int i = 0; i < str.length; i++)
     {
         for (int s = str[i].length()-1; s >= 0; s--)
         {
             rev.append(str[i].charAt(s));
         }
         rev.append(" ");
     }

     return rev.toString();
 }

Here is my conclusion for some of my tests:

     public static void main(String[] args)
     {
         System.out.println(reverse("I love chocolate"));//this passes
         System.out.println(reverse("Geeks for Geeks"));//this passes
         System.out.println(reverse("You, are awesome"));//not handling puncutation mark correctly, gives me ",uoY era emosewa", instead of "uoY, era emosewa"
         System.out.println(reverse("Geeks! for Geeks."));//not handling puncutation marks correctly, gives me "!skeeG rof .skeeG", instead of "skeeG! rof skeeG."
     }
+4
source share
4 answers

, , :

public static String reverse(String x)
{
     String[] str = x.split("\\W"); //Split on non-word characters.

     StringBuilder rev = new StringBuilder("");
     int currentPosition = 0;
     for (int i = 0; i < str.length; i++)
     {
         for (int s = str[i].length()-1; s >= 0; s--)
         {
             rev.append(str[i].charAt(s));
             currentPosition++;
         }
         while (currentPosition < x.length() && Character.toString(x.charAt(currentPosition)).matches("\\W")) 
            rev.append(x.charAt(currentPosition++)); //Add the actual character there.
     }

     return rev.toString();
 }

Java , , , , .

- O (n) ( ).

, , , , , , , .

+1

, , O(1). , O(N) .

, . swap() , . .

, - StringBuilder. - , Android, .

 public static void swap(StringBuilder input, int start, int end) {
    for (int i=0; i <= (end - start) / 2; ++i) {
        char ch = input.charAt(start + i);
        input.setCharAt(start + i, input.charAt(end - i));
        input.setCharAt(end - i, ch);
    }
}

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("I love chocolate");

    int start = 0;
    int end = 0;

    while (true) {
        while (end <= sb.length() - 1 && sb.charAt(end) != ' ') {
            ++end;
        }
        swap(sb, start, end - 1);
        start = end + 1;
        end = start;
        if (end > sb.length() - 1) {
            break;
        }
    }

    System.out.println(sb);
}

:

Rextester

+1

, , .

/* Soner - The methods reverse a string with preserving punctiations */
public static String reverse(String x) {
    String[] str = x.split(" ");
    boolean flag = false;
    int lastCharPosition;
    StringBuilder rev = new StringBuilder("");

    for (int i = 0; i < str.length; i++) {
        flag = false;
        lastCharPosition = str[i].length()-1;
        if (str[i].charAt(lastCharPosition) == '.' || str[i].charAt(lastCharPosition) == '!'
                || str[i].charAt(lastCharPosition) == ',') {  // you can add new punctiations
            flag = true;
            lastCharPosition = str[i].length()-2;
        }
        for (int s = lastCharPosition; s >= 0; s--) {
            rev.append(str[i].charAt(s));
        }
        if (flag) rev.append(str[i].charAt(lastCharPosition + 1));
        rev.append(" ");
    }

    return rev.toString();
}
+1

public static String reverse(String x) {
    Matcher m = Pattern.compile("\\w+").matcher(x);
    if(!m.find()) return x;
    StringBuffer target = new StringBuffer(x.length());
    do m.appendReplacement(target, new StringBuilder(m.group()).reverse().toString());
    while(m.find());
    return m.appendTail(target).toString();
}

appendReplacement loop + appendTail a Matcher String.replaceAll(regex), , , , , .

Unfortunately, we must use the deprecated one StringBufferhere since the API is older StringBuilder. Java 9 is going to change that .

A potentially more effective alternative is

public static String reverse(String x) {
    Matcher m = Pattern.compile("\\w+").matcher(x);
    if(!m.find()) return x;
    StringBuilder target = new StringBuilder(x.length());
    int last=0;
    do {
        int s = m.start(), e = m.end();
        target.append(x, last, s).append(new StringBuilder(e-s).append(x, s, e).reverse());
        last = e;
    }
    while(m.find());
    return target.append(x, last, x.length()).toString();
}

This uses StringBuilderthroughout the operation and uses the function of adding partial sequences of characters without creating intermediate lines for matching and replacing. It also speeds up the search for placeholders in replacements that appendReplacementit does internally.

+1
source

Source: https://habr.com/ru/post/1680857/


All Articles