Hi i have a beginner question about nested for-loop in java.
int sum = 0;
for(int i = 1; i < 3; i++){
for(int j = i; j>= 0; j--){
sum += j;
}
}
so here is my trace table
i j sum
1 1 1
0 1
2 2 2
1 3
0 3
My question is why is the output at the end of the loop is 4? is it because 3+1?
Your trace table is wrong. This is the correct one:
i j sum
1 1 1
0 1
2 2 3
1 4
0 4
You sum all values of j (second column), which essentially is 1 + 0 + 2 + 1 + 0 = 4.
Actually we need to make a correction for your table result:
i j sum
1 1 1
0 1
2 2 2 (sum is 2+1(existing sum, sum is not 0 anymore) )
1 3 (sum is 3 + 1 = 4)
0 3 (sum is 4+ 0 = 4)
The output is 4 because sum is:
0 +
1 +
2 + 1 =
= 4
First you add 1, then 2 and 1. Your loops sums all triangle numbers below 3. Triangle numbers are sums of numbers from 1 to n. These are 1, 3, 6, 10 etc..
Related
I was given a task during an interview, where I was given a matrix, now I need to generate another matrix out of it using below formula:
Given matrix A[R][C], generate B[R][C]
val = 0;
for (i = 0; i ≤ xPosition; i += 1) {
for (j = 0; j ≤ yPosition; j += 1) {
val = val + a(i, j);
}
}
B(xPosition,yPosition) = val;
I have come up with below code:
public List<List<Integer>> generate(List<List<Integer>> A) {
List<List<Integer>> top = new ArrayList<>();
for (int i = 0; i < A.size(); i++) {
List<Integer> inner = new ArrayList<>();
for (int j = 0; j < A.get(0).size(); j++) {
inner.add(generateValue(A, i, j));
}
top.add(inner);
}
return top;
}
int generateValue(List<List<Integer>> A, int xPosition, int yPosition) {
int val = 0;
for (int i = 0; i <= xPosition; i++) {
for (int j = 0; j <= yPosition; j++) {
int value = A.get(i).get(j);
val += value;
}
}
return val;
}
Sample input :
1 2 3
4 5 6
Output :
1 3 6
5 12 21
How to improve the performance of this logic?
mathematicaly for your solution in array b,each element is related to it's previous one.
to improve your code / optimise it you need to see this relation.
so for every B[i][j] is related to it's previous element and value from the array A.
below is solution mathematically,
b[i][j] = b[i-1][j] + a[i][0]+a[i][1] + a[i][2]+...+a[i][y-1]
for so if you able to implement this, your code will pass all test cases
i am not a java dev, but if you want code, i can write it for you in python
The key is to think of this as a dynamic programming problem, assuming that we have already calculated B[x][y] for all 0 <= x < i, 0 <= y < j when we go to calculate B[i][j].
B[i][j] contains the sum of all elements in the submatrix of A that starts at 0, 0 and ends at i, j. Thus B[i-1][j] will contain the sum of the all the elements in this submatrix except the ones in the ith row. Similarly, B[i][j-1] will contain the sum of the all the elements in this submatrix except the ones in the jth column. Adding these two together, we get the sum of all the elements in the submatrix except for element A[i][j]. However, while doing this we count all the elements from 0, 0 to i-1, j-1 twice, and we have to subtract their sum (which is B[i-1][j-1]) once so that we only sum them up once in total. Then we add the missing element, A[i][j]. Hence
B[i][j] = B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j]
This recursion can now be implemented as a O(RC) dynamic programming algorithm.
To help understand this further, consider the following figure representing the submatrix for which we have to find the sum of the elements. The figure is a matrix C[i][j], where the x, yth element is the number of times we have summed A[x][y]. In terms of C[i][j], our end goal (B[i][j]) is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
B[i-1][j] corresponds to the matrix C[i-1][j], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 0 0 0 0
B[i][j-1] corresponds to the matrix C[i][j-1], which is
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
1 1 1 1 0
B[i-1][j] + B[i][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1], which is
2 2 2 2 1
2 2 2 2 1
2 2 2 2 1
1 1 1 1 0
B[i-1][j] + B[i][j-1] - B[i-1][j-1] corresponds to the matrix C[i-1][j] + C[i][j-1] - C[i-1][j-1], which is
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 0
Now B[i-1][j] + B[i][j-1] - B[i-1][j-1] + A[i][j] corresponds to
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
which is the same as B[i][j].
I am trying to make a table from 1 - 5, which displays there power up to 6 values.
so for example, the 2 column would go from, 1,2,4,8,16,32,64 and would stop there.
I am having trouble getting proper table format. Since the numbers don't align where they should be.
for example:
the problem I am facing right now is this
1 2 3 4 5
1 1 1 1 1 1 1 2 4 8 16 and so and so on
any well would be appreciated, my code is down below.
int powNumb=5;
int powValue=6;
for (int i = 1; i <= powValue; i++) {
System.out.printf("%10d",i);
}
System.out.println();
for (int i = 1; i <= powNumb; i++) {
for (int j = 0; j <=powValue; j++) {
System.out.printf("%10.0f",Math.pow(i, j));
}
}
This should help you
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10d", i); //Print the number (1st col)
for (int j = 0; j <= powValue; j++) { //This loop prints the powers of the curent number 'i'
System.out.printf("%10.0f", Math.pow(i, j));
}
System.out.println(); //To end the current row
}
This prints
num num^0 num^1 num^2 ... num^powValue
where num is from 1 to powNumb
Output
1 1 1 1 1 1 1 1
2 1 2 4 8 16 32 64
3 1 3 9 27 81 243 729
4 1 4 16 64 256 1024 4096
5 1 5 25 125 625 3125 15625
You mean the same base for every element, so there is no need for inner loop:
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10.0f", Math.pow(powValue, i));
}
This way the base of power is always powValue.
First, you need a println statement somewhere in your inner for loop to separate the rows.
Second, you need to switch the i and j in your call to Math.pow. Because with how it's currently set up, each row is value i = row number to powers 0 through 6. For example, the first row would be 1^0 1^1 1^2 1^3 1^4 1^5 1^6. Then, the second row would be 2^0 2^1 2^2 2^3 2^4 2^5 2^6 However, you want the first row to be 1^0 2^0 3^0 4^0 5^0, second row 1^1 2^1 3^1 4^1 5^1, etc. So your code should be changed to something like this,
int powNumb=5;
int powValue=6;
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10d",i);
}
for (int i = 0; i <= powValue; i++) {
System.out.println();
for (int j = 1; j <=powNumb; j++) {
System.out.printf("%10.0f",Math.pow(j, i));
}
}
Output:
1 2 3 4 5
1 1 1 1 1
1 2 3 4 5
1 4 9 16 25
1 8 27 64 125
1 16 81 256 625
1 32 243 1024 3125
1 64 729 4096 15625
Also, I had to switch powNumb and powValue in the for loop conditions.
I'm wondering what is the difference between these loops in 2D arrays:
for (int r = row - 1, c = column - 1; r >= 0 && c >= 0; r--, c--) {
...
}
for(int r=row-1;r>=0;r--){
for(int c=column-1;c>=0;c--){
...
}
}
for (int r = row - 1, c = column - 1; r >= 0 && c >= 0; r--, c--)
The first example is one loop that decrements both r and c every cycle, meaning that the indices r and c will draw a diagonal starting at array[row-1][column-1].
for(int r=row-1;r>=0;r--){
for(int c=column-1;c>=0;c--){
The second example calls a loop for columns for each index of row, so it will access all the indices array[r][c]
I assume you are asking for the difference between a single outer loop and a nested loop. The difference is that the single loop will iterate over the diagonal of the 2D array and the nested loops with iterate over every index of the array. For instance, if there are 6 rows and 4 columns then:
for (int r = row - 1, c = column - 1; r >= 0 && c >= 0; r--, c--) {
System.out.println(r + " " + c);
}
will yield:
5 3
4 2
3 1
2 0
Whereas the nested loop
for(int r=row-1; r>=0; r--) {
for(int c=column-1; c>=0; c--) {
System.out.println(r + " " + c);
}
}
would yield
5 3
5 2
5 1
5 0
4 3
4 2
4 1
4 0
3 3
3 2
3 1
3 0
2 3
2 2
2 1
2 0
1 3
1 2
1 1
1 0
0 3
0 2
0 1
0 0
The first iterates for n times, where n is the least of row and column. The second iterates for m times, where m is row * column. That is
Math.min(row, column)
and
row * column
respectively.
I'm stuck trying to create a 3 x 2 matrix that only contains 0 and 1 and prints out all the possible combinations, BUT it can only contain one 1 and one 0 for each row, the numbers have nothing to do with each other than that they are unique, much like a betting table for say tennis or something:
0 1 1 0 0 1 0 1 0 1
0 1 1 0 0 1 1 0 1 0
0 1 1 0 1 0 1 0 0 1
Here's the code:
public class Program {
public static void main(String[] args) {
int[][] array = {{0,1}};
System.out.println("Array:");
for(int row = 0; row < array.length; row++){
for(int column = 0; column < array[row].length; column++){
System.out.print(array[row][column] + " ");
}
System.out.println();
}
}
}
This is what I got right know. I don't know where to take it from here.
For a general case of an N-by-2 matrix there will be 2^N combinations that meet your criteria. Consider that each row can only be in two states: [0, 1], or [1, 0].
Start with a matrix where every row is in the initial state [0, 1]. Then, for every number X where 0 <= X < 2^N, convert X to binary. When the Mth bit is 1, reverse the Mth row's values.
For example, binary 000 would correspond to:
0 1
0 1
0 1
While binary 101 would correspond to:
1 0 (swapped)
0 1
1 0 (swapped)
It was so hard to ask such a newbie question on this advanced site. But after so much tries and even loosing my hope i was forced to bring my self here. I am not been able to print the following pattern:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
But with my tiresome efforts i reached the following:
public static void main(String[] args) {
int num = 1;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15 - i; j++) {
System.out.print(" ");
}
for (int k = 0; k <= i; k++) {
System.out.print(num + " ");
}
System.out.println();
}
}
1
1 1
1 1 1
1 1 1 1
1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1
Here ya go
public static void main(String[] args) {
int max = 6;
int padLength = (int) Math.ceil(Math.log10(Math.pow(2, max) + 1)) + 2;
for (int i = 0; i < max; i++) {
for (int j = 1; j < max - i; j++) {
System.out.print(pad(" ", padLength));
}
for (int k = 0; k <= i; k++) {
System.out.print(pad(Math.pow(2, k), padLength));
}
for (int k = i - 1; k >= 0; k--) {
System.out.print(pad(Math.pow(2, k), padLength));
}
System.out.println();
}
}
public static String pad(double d, int l) {
Integer i = (int) d;
return pad(i.toString(), l);
}
public static String pad(String s, int l) {
return String.format("%-" + l + "s", s);
}
Explanation
int padLength = (int) Math.ceil(Math.log10(Math.pow(2, max) + 1)) + 2;
Math.pow(2,max) - Gives me maximal number I will have to display
Math.ceil(Math.log10(number + 1)) - I use this to determine length of string representation of specific number. Please refer to wikipedia to check what logarithm is. I add 1 to skip edge case when number is exact power of 10 e.g. log10(10)->1 (this will never occur in task specified in question, it's just for purity of solution). Ceil just rounds number up.
+2 - minimum gap between two numbers is specified example was 2 spaces long so I just add this
You could use here Integer.toString(((int)Math.pow(2, max))).length()+2 but it's not as pretty :)
return String.format("%-" + l + "s", s);
First I build format string that looks like e.g. %-3s, which means print String with minimum length of 3, padding on the right. Second argument is the String I want to print. Refer to documentation
Running example
I find the other answer very overwhelming and dramatic. You don't need much maths and complexity to solve this problem. This might not be the best code but I think it is easy to understand. Not even an explanation is needed, it is a row by row approach, It's good to keep things simple.
public static void main(String[] args) {
// Init
int row = 0;
int maxRows = 6;
int num = 1;
int indent = maxRows - 1;
// Printing loop
while (row < maxRows) {
// Indent
for (int i = 0; i < indent; ++i)
System.out.print(" ");
// Print nums
for (int i = 0; i < num; ++i)
System.out.printf("%4d", (int) Math.pow(2.0, i));
for (int i = num - 2; i >= 0; --i)
System.out.printf("%4d", (int) Math.pow(2.0, i));
// New line
System.out.println("");
// Adjustments
++row;
--indent;
++num;
}
Output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1