Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow Stack Overflow.

You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.

You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.

Source Link
Brythan
  • 7k
  • 3
  • 22
  • 37
public void steppingNumber(int s, int e) {

As described in the problem statement, s is the starting number and e is the ending number. Why not call them start and end then? That way we don't have to refer to the problem statement to know what the variables mean.

I would also pick another name for the function. You are printing the stepping numbers, so call it printSteppingNumbers. As a general rule, functions should have verb names. They do things and their names should reflect that.

 String str = String.valueOf(s);

Why a string? In C, this would make sense as the difference between a letter and a number in C is trivial (char is an integer type). Java isn't as forgiving. Even if you do want a string, this is the wrong place to do it. Call the function with s (or start).

 if ( isSteppingNumber(start) ) {
 System.out.print(start + " ");
 }

I added braces ({}) around the then clause. This helps avoid a class of error where someone intends to add a new statement to the then clause but actually makes it run whether the if triggers or not. I also find it easier to read.

List<String> numbers = new ArrayList<>();
while(str.length() >= 3) { // get every 3-digit comma-separated number
 numbers.add(str.substring(str.length()-3));
 str = str.substring(0,str.length()-3);
}

This seems overly complicated. You don't need to generate a List here. It's sufficient to check each chunk as you go through.

while ( str.length() > 3 ) {
 if ( ! isSteppingSequence(str.substring(str.length()-3)) ) {
 return false;
 }
 str = str.substring(0,str.length()-3);
}
return isSteppingSequence(str);

You also don't need >= here. A simple > is better, as you always want there to be one chunk left to test outside the loop.

But we can do better if we keep it as a number at this point. First, we need a constant.

private final static int CHUNK_SIZE = 1000;

Now we can use it.

 while ( number > CHUNK_SIZE ) {
 if ( ! isSteppingSequence(number % CHUNK_SIZE) ) {
 return false;
 }
 number /= CHUNK_SIZE;
 }
 return isSteppingSequence(number);

Another constant.

private final static int BASE = 10;

Now we just need to define isSteppingSequence and we get:

private final static int BASE = 10;
private final static int CHUNK_SIZE = 1000;
private static void listSteppingNumbers(int start, int end) {
 while ( start <= end ) {
 if ( isSteppingNumber(start) ) {
 System.out.print(start + " ");
 }
 start++;
 }
}
private static boolean isSteppingNumber(int number) {
 if ( number < BASE ) {
 return false;
 }
 while ( number > CHUNK_SIZE ) {
 if ( ! isSteppingSequence(number % CHUNK_SIZE) ) {
 return false;
 }
 number /= CHUNK_SIZE;
 }
 // all the other sequences were stepping, so 
 // if this one is, it's a valid stepping number
 // otherwise not
 return isSteppingSequence(number);
}
private static boolean isSteppingSequence(int number) {
 int previous_digit = number % BASE;
 number /= BASE;
 while ( number > 0 ) {
 int current_digit = number % BASE;
 if ( Math.abs(previous_digit - current_digit) != 1 ) {
 return false;
 }
 previous_digit = current_digit;
 number /= BASE;
 }
 // if number was less than BASE, then it skipped the while loop
 // and all single digit numbers are valid stepping sequences
 // so true
 // if it made it through the while loop, 
 // all the adjacent digits differed by 1
 // so true
 return true;
}

So we now have a more readable version of your initial algorithm. Since it doesn't convert to a String and from characters, I suspect that it will be slightly faster.

You also ask if we can do better than stepping through every number in the range and testing to see if it is a stepping number. Certainly we can. We can generate the stepping numbers by composition. We don't have to search for them. I notice that this is described in more detail on Stack Overflow.

lang-java

AltStyle によって変換されたページ (->オリジナル) /