简体   繁体   中英

How can I optimize This Code Into Lesser Line of Code

How can I optimize this code.

I want to reduce lines of code.

public class CoolDude {
    public static void main(String[] args) {
        for(int i = 100; i <= 500; ++i) {
            if(i%5 == 0 && i%11 == 0) {
                System.out.print("Cool Dude- ");
                System.out.print(i + "\n");
            } else if (i%5 == 0) {
                System.out.print("Cool - ");
                System.out.print(i + "\n");
            } else if (i%11 == 0) {
                System.out.print("Dude - ");
                System.out.print(i + "\n");
            }
        }
    }

}

Is there any way ?

You could restructure your decision tree such that there will only ever have to be 2 checks (each with 1 operation and 1 comparison) against the number in the loop. Currently, your decision tree requires 2 operations and 2 comparisons in the best case ( i is divisible by both 5 and 11) and 4 operations and 4 comparisons in the worst case ( i is not divisible by either 5 or 11), but we can reduce that to always be just 2 comparisons and 2 operations, which will result in a more performant loop. In this way, i is only ever tested for divisibility against 5 and 11 one time for each number, so only 2 operations and 2 comparisons will need to be done no matter what the stage of the loop. This is the sort of optimization you should be looking at when trying to optimize a loop.

I also made your print method calls a printf call instead, reducing two print statements into 1. Here is a printf cheat sheet that you can use if you are unfamiliar with it.

Now, doing all this only reduced the size of your code by 1 line, and while I am sure that could be reduced further with some clever use of ternary operators or other methods, as a general rule, measuring code quality by number of lines is a terrible metric, and should never be used, particularly when we are talking about a compiled language like Java. There are a lot of things I could do to the code below that would reduce the line count at the expense of readability and/or performance, but there is no real point to that outside of competitions between programmers, like code golf (but even with that you are competing for the lowest character count, not line count).

Instead of shooting for shorter code, you should instead be striving for the best Big-O notation complexity so that your code is more performant, and fewer lines of code does not necessarily correlate with performance.

public class CoolDude {
    public static void main(String[] args) {
        for (int i = 100; i <= 500; ++i) {
            if (i % 5 == 0) {
                if (i % 11 == 0) {
                    System.out.printf("Cool Dude - %d\n", i);
                } else {
                    System.out.printf("Cool - %d\n", i);
                }
            } else if (i % 11 == 0) {
                System.out.printf("Dude - %d\n", i);
            }
        }
    }
}

While Stephen M Irving's answer is pretty spot on and corrects all the beliefs found in your question, this still answers your question, trying to minimize the number of statements.

public class CoolDude {
  public static void main(String[] args) {
    for (int i = 100; i <= 500; i++)
      if (i % 5 == 0 || i % 11 == 0) // This is the condition where we decide to print something
        System.out.printf("%s%s- %d%n", i % 5 == 0 ? "Cool " : "", i % 11 == 0 ? "Dude " : "", i);
  }
}

However, this code duplicates one of the most expensive part: the modulo. Also, this solution is not readable !

When trying to figure solutions is useful to try several KPI and then find the best to optimize. In this case, you wanted to optimize the number of lines, it's definitely not the best as you can see above. If anything try first to get a working solution then a readable one and finally an optimized one where you document why it's optimized so that the readability is maintained.

Here, for instance, is the most optimized version I could come up with. It definitely contains more lines, but also is definitely faster, since I skip all invalid numbers and never do a modulo (only two divisions and two multiplications for the whole program).

public class CoolDude {
  public static void main(String[] args) {
    final int min = 100;
    final int max = 500;
    for (int i5 = nextMultiple(min, 5), i11 = nextMultiple(min, 11); i5 <= max || i11 <= max; ) {
      if (i5 < i11) {
        System.out.printf("Cool - %d%n", i5);
        i5 += 5;
      } else if (i11 < i5) {
        System.out.printf("Dude - %d%n", i11);
        i11 += 11;
      } else { // i5 == i11
        System.out.printf("Cool Dude - %d%n", i5);
        i5 += 5;
        i11 += 11;
      }
    }
  }
  static int nextMultiple(int number, int divisor) {
    int roundToLower = (number - 1) / divisor * divisor;
    return roundToLower + divisor;
  }
}
        IntStream.rangeClosed(100,500).forEach(i->{
        if(i%5 == 0 && i%11 == 0) {
            System.out.println("Cool Dude - "+i );
        } else if (i%5 == 0) {
            System.out.println("Cool - "+i );
        } else if (i%11 == 0) {
            System.out.println("Dude - "+i );
        }
    });

The below should reduce lines of code, though it does not appear to run faster. It also corrects spacing around the hyphen and perhaps simplifies the logic.

public class CoolDude {
public static void main(String args[]) {
    for (int i = 100; i <= 500; ++i) {
        StringBuilder coolDude = new StringBuilder(15); //15 chars max "Cool Dude - 495"
        if (i % 5 == 0) {
            coolDude.append("Cool ".toCharArray());
        }
        if (i % 11 == 0) {
            coolDude.append("Dude ".toCharArray());
        }
        if (coolDude.length() > 0) {
            System.out.println(coolDude.append(("- " + i).toCharArray()));
        }
    }
}
}

REVISION: My point was that it was possible to take advantage of being able to do each mod calculation only once each time through the loop. That got lost in trying to save time with StringBuilders and a single line (which, as others pointed out, isn't a worthy goal). I clarified by using print and println instead.

public class CoolDude {
public static void main(String args[]) {
    boolean printed = false;
    for (int i = 100; i <= 500; ++i, printed = false) {
        if (i % 5 == 0) {
            System.out.print("Cool ");
            printed = true;
        }
        if (i % 11 == 0) {
            System.out.print("Dude ");
            printed = true;
        }
        if (printed) {
            System.out.println("- " + i);
        }
    }
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM