1

I am new to Java and looking for code optimization techniques. This code is giving the expected output using two for loops and I want to reduce/eliminate the loops (if possible).

public static void main(String[] args) {
        String dummy = "Hello how are you";
        String[] strArr = dummy.split(" ");
        for(int i=0; i < strArr.length;i++){
            String word = strArr[i];
            for(int j=word.length(); j > 0; j--){
                System.out.print(word.charAt(j - 1));
            }
            System.out.print(" ");
        }
    }

Output: olleH woh era uoy

Please advice.

9
  • 1
    This belongs on CodeReview Commented Aug 20, 2017 at 15:59
  • 1
    I am not asking for CodeReview, rather the optimization techniques. Commented Aug 20, 2017 at 15:59
  • It is impossible to reduce the number of loops. You can change the type of loop to a while or a do-while loop but you need at least 2 looping constructs if you want your code to work Commented Aug 20, 2017 at 16:02
  • 3
    The problem with this question is that you did not present a problem - you are prematurely optimizing. This doesn't cause a bottleneck, you don't specify any time requirements, etc.. You just wanna "optimize" it, which doesn't make much sense without context. What do you feel is wrong with your code? Commented Aug 20, 2017 at 16:10
  • 1
    @user182944: Added an example where you "unnest" the for loops. Commented Aug 20, 2017 at 16:39

3 Answers 3

5

Since the complexity of printing the output would remain the same, all you can do is to "hide" the loops into existing methods that do what you want, not eliminate them, because the amount of work the system needs to perform remains the same in terms of the number of characters that need to be processed.

You can hide the nested loop by using string reversal technique described in this Q&A. The outer loop can be pushed into String.join:

String[] data = {"quick", "brown", "fox"};
System.out.println(
    String.join(
        " "
    ,   Arrays.stream(data)
           .map(s -> new StringBuilder(s).reverse().toString())
           .toArray(String[]::new)
    )
);

Demo.

Sign up to request clarification or add additional context in comments.

1 Comment

@GilVegliach .collect(Collectors.joining(" ")) would be cooler.
1

As I stated in my comment the complexity is already O(n) and you cannot get better because you need to read the input string. Anyway, there is a way to "unnest" the two for loops: reverse the whole string, split on spaces, and reverse the resulting array.

Example:

"Hello how are you"
"uoy era woh olleH"
"uoy" "era" "woh" "olleH"
"olleH" "woh" "era" "uoy" 

Code:

public static void main(String[] args) {
    String dummy = "Hello how are you";

    int n = dummy.length();
    StringBuilder sb = new StringBuilder(n);
    while (--n >= 0) sb.append(dummy.charAt(n));

    String[] tokens = sb.toString().split(" ");
    n = tokens.length;
    while (--n >= 0) System.out.print(tokens[n] + " ");
}

Instead, if you are after cools java 8 Stream tricks, read dasblinkenlight's answer.

Comments

1

This is another simple solution using StringTokenizer.

It takes only O(n).

public static void main(String[] args) {

    System.out.println(reverseStringWordByWord("Hello How are you"));

}

public static String reverseStringWordByWord(String input) {
    StringBuilder result = new StringBuilder();
    StringTokenizer sToken = new StringTokenizer(input, " ");
    while (sToken.hasMoreTokens()) {
        StringBuilder thisToken = new StringBuilder(sToken.nextToken());
        result.append(thisToken.reverse() + " ");
    }
    return result.toString();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.