I am doing the following programming exercise: Complete The Pattern #4. The statement is:
Task:
You have to write a function pattern which creates the following pattern upto n number of rows. If the Argument is 0 or a Negative Integer then it should return "" i.e. empty string.
Examples:
pattern(4):
1234 234 34 4
pattern(6):
123456 23456 3456 456 56 6
Note: There are no blank spaces
Hint: Use \n in string to jump to next line
I have tried the following naive solution:
public class Pattern {
public static String pattern/*🅿️*/(int n) {
String result = "";
for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j++){
result += j;
}
result += "\n";
}
return result.strip();
}
}
Which runs out of time (the execution time is longer than 16000 ms) for input of three digits like: 496, 254, 529...
Then, I tried to simplify it, removing the nested loop and just iterating a first time to put all the numbers range, and then iterating a second time to append the rest of the pattern:
public class Pattern {
public static String pattern/*🅿️*/(int n) {
System.out.println("n: "+n);
String result = "";
for(int i = 1; i <= n; i++){
result += i;
}
System.out.println("result after first loop: "+result);
for(int i = 1; i < n; i++){
result += "\n"+result.substring(i,n);
}
System.out.println("result after second loop:\n"+result);
return result.strip();
}
}
I have been debugging and I have found that this second solution outputs correct only when n is a one digit number. For example when n is 7:
n: 7
result after first loop: 1234567
result after second loop:
1234567
234567
34567
4567
567
67
7
However, when n is a two digits number:
n: 11
result after first loop: 1234567891011
result after second loop:
1234567891011
2345678910
345678910
45678910
5678910
678910
78910
8910
910
10
0
And the output should be:
Expected...
<...567891011
2345678910[11
34567891011
4567891011
567891011
67891011
7891011
891011
91011
1011
11]>
But was...
expected:<...567891011
2345678910[
345678910
45678910
5678910
678910
78910
8910
910
10
0]>
Being the test cases (extracted from the exercise):
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class PatternTest {
@Test
public void pattern() throws Exception {
assertEquals( Pattern.pattern( 1 ), "1" );
assertEquals( Pattern.pattern( 2 ), "12\n2" );
assertEquals( Pattern.pattern( 5 ), "12345\n2345\n345\n45\n5" );
assertEquals( Pattern.pattern( 7 ), "1234567\n234567\n34567\n4567\n567\n67\n7" );
assertEquals( Pattern.pattern( 11 ), "1234567891011\n234567891011\n34567891011\n4567891011\n567891011\n67891011\n7891011\n891011\n91011\n1011\n11" );
assertEquals( Pattern.pattern( 0 ), "" );
assertEquals( Pattern.pattern( -25 ), "" );
assertEquals( Pattern.pattern( -59 ), "" );
}
}
I understand the bug is with result.substring(i,n)
because of we are assuming that each number will count as 1 in the oop (will only have one digit), which is incorrect, it could have more digits...
How could we improve this code?‽
I have also read:
- How correctly convert this String using substring() Java method?
- How does the Java 'for each' loop work?
Aucun commentaire:
Enregistrer un commentaire